nir: add vec2_index_32bit_offset address format

For turnip, we use the "bindless" model on a6xx. Loads and stores with
the bindless model require a bindless base, which is an immediate field
in the instruction that selects between 5 different 64-bit "bindless
base registers", a 32-bit descriptor index that's added to the base, and
the usual 32-bit offset. The bindless base usually, but not always,
corresponds to the Vulkan descriptor set.  We can handle the case where
the base is non-constant by using a bunch of if-statements, to make it a
little easier in core NIR, and this seems to be what Qualcomm's driver
does too. Therefore, the pointer format we need to use in NIR has a vec2
index, for the bindless base and descriptor index. Plumb this format
through core NIR.

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Kristian H. Kristensen <hoegsberg@google.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5683>
This commit is contained in:
Connor Abbott
2020-06-29 19:47:57 +02:00
committed by Marge Bot
parent 7ab7316003
commit 12e18d9e7a
3 changed files with 70 additions and 36 deletions

View File

@@ -784,6 +784,10 @@ build_addr_iadd(nir_builder *b, nir_ssa_def *addr,
assert(addr->num_components == 2);
return nir_vec2(b, nir_channel(b, addr, 0),
nir_iadd(b, nir_channel(b, addr, 1), offset));
case nir_address_format_vec2_index_32bit_offset:
assert(addr->num_components == 3);
return nir_vec3(b, nir_channel(b, addr, 0), nir_channel(b, addr, 1),
nir_iadd(b, nir_channel(b, addr, 2), offset));
case nir_address_format_logical:
unreachable("Unsupported address format");
}
@@ -802,18 +806,30 @@ static nir_ssa_def *
addr_to_index(nir_builder *b, nir_ssa_def *addr,
nir_address_format addr_format)
{
assert(addr_format == nir_address_format_32bit_index_offset);
assert(addr->num_components == 2);
return nir_channel(b, addr, 0);
if (addr_format == nir_address_format_32bit_index_offset) {
assert(addr->num_components == 2);
return nir_channel(b, addr, 0);
} else if (addr_format == nir_address_format_vec2_index_32bit_offset) {
assert(addr->num_components == 3);
return nir_channels(b, addr, 0x3);
} else {
unreachable("bad address format for index");
}
}
static nir_ssa_def *
addr_to_offset(nir_builder *b, nir_ssa_def *addr,
nir_address_format addr_format)
{
assert(addr_format == nir_address_format_32bit_index_offset);
assert(addr->num_components == 2);
return nir_channel(b, addr, 1);
if (addr_format == nir_address_format_32bit_index_offset) {
assert(addr->num_components == 2);
return nir_channel(b, addr, 1);
} else if (addr_format == nir_address_format_vec2_index_32bit_offset) {
assert(addr->num_components == 3);
return nir_channel(b, addr, 2);
} else {
unreachable("bad address format for offset");
}
}
/** Returns true if the given address format resolves to a global address */
@@ -841,6 +857,7 @@ addr_to_global(nir_builder *b, nir_ssa_def *addr,
nir_u2u64(b, nir_channel(b, addr, 3)));
case nir_address_format_32bit_index_offset:
case nir_address_format_vec2_index_32bit_offset:
case nir_address_format_32bit_offset:
case nir_address_format_logical:
unreachable("Cannot get a 64-bit address with this address format");
@@ -1284,7 +1301,8 @@ lower_explicit_io_array_length(nir_builder *b, nir_intrinsic_instr *intrin,
unsigned stride = glsl_get_explicit_stride(deref->type);
assert(stride > 0);
assert(addr_format == nir_address_format_32bit_index_offset);
assert(addr_format == nir_address_format_32bit_index_offset ||
addr_format == nir_address_format_vec2_index_32bit_offset);
nir_ssa_def *addr = &deref->dest.ssa;
nir_ssa_def *index = addr_to_index(b, addr, addr_format);
nir_ssa_def *offset = addr_to_offset(b, addr, addr_format);
@@ -1582,6 +1600,7 @@ nir_address_format_null_value(nir_address_format addr_format)
[nir_address_format_64bit_global] = {{0}},
[nir_address_format_64bit_bounded_global] = {{0}},
[nir_address_format_32bit_index_offset] = {{.u32 = ~0}, {.u32 = ~0}},
[nir_address_format_vec2_index_32bit_offset] = {{.u32 = ~0}, {.u32 = ~0}, {.u32 = ~0}},
[nir_address_format_32bit_offset] = {{.u32 = ~0}},
[nir_address_format_logical] = {{.u32 = ~0}},
};
@@ -1599,6 +1618,7 @@ nir_build_addr_ieq(nir_builder *b, nir_ssa_def *addr0, nir_ssa_def *addr1,
case nir_address_format_64bit_global:
case nir_address_format_64bit_bounded_global:
case nir_address_format_32bit_index_offset:
case nir_address_format_vec2_index_32bit_offset:
case nir_address_format_32bit_offset:
return nir_ball_iequal(b, addr0, addr1);
@@ -1631,6 +1651,12 @@ nir_build_addr_isub(nir_builder *b, nir_ssa_def *addr0, nir_ssa_def *addr1,
/* Assume the same buffer index. */
return nir_isub(b, nir_channel(b, addr0, 1), nir_channel(b, addr1, 1));
case nir_address_format_vec2_index_32bit_offset:
assert(addr0->num_components == 3);
assert(addr1->num_components == 3);
/* Assume the same buffer index. */
return nir_isub(b, nir_channel(b, addr0, 2), nir_channel(b, addr1, 2));
case nir_address_format_logical:
unreachable("Unsupported address format");
}