FMT(R9G9B9E5_FLOAT, R9F_G9F_B9F_E5F, RGB1, L, VT__),
FMT(R8_SNORM, R8_SNORM, R001, L, VT__),
FMT(R16_SNORM, R16_SNORM, R001, L, VT__),
- FMT(R32_SNORM, R32_SNORM, R001, L, VT__),
FMT(R8G8_SNORM, RG8_SNORM, RG01, L, VT__),
FMT(R16G16_SNORM, RG16_SNORM, RG01, L, VT__),
- FMT(R32G32_SNORM, RG32_SNORM, RG01, L, VT__),
FMT(R8G8B8_SNORM, RGB8_SNORM, RGB1, L, VT__),
- FMT(R32G32B32_SNORM, RGB32_SNORM, RGB1, L, VT__),
FMT(R8G8B8A8_SNORM, RGBA8_SNORM, RGBA, L, VT__),
FMT(R16G16B16A16_SNORM, RGBA16_SNORM, RGBA, L, VT__),
- FMT(R32G32B32A32_SNORM, RGBA32_SNORM, RGBA, L, VT__),
FMT(I8_SINT, R8I, RRRR, L, VTR_),
FMT(L8_SINT, R8I, RRR1, L, VTR_),
FMT(I8_UINT, R8UI, RRRR, L, VTR_),
FMT(R32G32B32_FLOAT, RGB32F, RGB1, L, VTR_),
FMT(R32G32B32A32_FLOAT, RGBA32F, RGBA, L, VTR_),
FMT(R8_UNORM, R8_UNORM, R001, L, VTR_),
- FMT(R16_UNORM, R16_UNORM, R001, L, VT__),
- FMT(R32_UNORM, R32_UNORM, R001, L, VT__),
+ FMT(R16_UNORM, R16_UNORM, R001, L, VTR_),
FMT(R8G8_UNORM, RG8_UNORM, RG01, L, VTR_),
- FMT(R16G16_UNORM, RG16_UNORM, RG01, L, VT__),
- FMT(R32G32_UNORM, RG32_UNORM, RG01, L, VT__),
+ FMT(R16G16_UNORM, RG16_UNORM, RG01, L, VTR_),
FMT(R8G8B8_UNORM, RGB8_UNORM, RGB1, L, VTR_),
+ /* 32-bit NORM is not texturable in v7 onwards. It's renderable
+ * everywhere, but rendering without texturing is not useful.
+ */
+#if PAN_ARCH <= 6
+ FMT(R32_UNORM, R32_UNORM, R001, L, VTR_),
+ FMT(R32G32_UNORM, RG32_UNORM, RG01, L, VTR_),
+ FMT(R32G32B32_UNORM, RGB32_UNORM, RGB1, L, VT__),
+ FMT(R32G32B32A32_UNORM, RGBA32_UNORM, RGBA, L, VTR_),
+ FMT(R32_SNORM, R32_SNORM, R001, L, VT__),
+ FMT(R32G32_SNORM, RG32_SNORM, RG01, L, VT__),
+ FMT(R32G32B32_SNORM, RGB32_SNORM, RGB1, L, VT__),
+ FMT(R32G32B32A32_SNORM, RGBA32_SNORM, RGBA, L, VT__),
+#else
+ FMT(R32_UNORM, R32_UNORM, R001, L, V___),
+ FMT(R32G32_UNORM, RG32_UNORM, RG01, L, V___),
+ FMT(R32G32B32_UNORM, RGB32_UNORM, RGB1, L, V___),
+ FMT(R32G32B32A32_UNORM, RGBA32_UNORM, RGBA, L, V___),
+ FMT(R32_SNORM, R32_SNORM, R001, L, V___),
+ FMT(R32G32_SNORM, RG32_SNORM, RG01, L, V___),
+ FMT(R32G32B32_SNORM, RGB32_SNORM, RGB1, L, V___),
+ FMT(R32G32B32A32_SNORM, RGBA32_SNORM, RGBA, L, V___),
+#endif
+
/* Don't allow render/texture for 48-bit */
FMT(R16G16B16_UNORM, RGB16_UNORM, RGB1, L, V___),
FMT(R16G16B16_SINT, RGB16I, RGB1, L, V___),
FMT(R16G16B16_SSCALED, RGB16I, RGB1, L, V___),
FMT(R16G16B16_SNORM, RGB16_SNORM, RGB1, L, V___),
FMT(R16G16B16_UINT, RGB16UI, RGB1, L, V___),
-
-#if PAN_ARCH <= 6
- FMT(R32G32B32_UNORM, RGB32_UNORM, RGB1, L, VT__),
-#else
- FMT(R32G32B32_UNORM, RGB32_UNORM, RGB1, L, V___),
-#endif
FMT(R4G4B4A4_UNORM, RGBA4_UNORM, RGBA, L, VTR_),
FMT(B4G4R4A4_UNORM, RGBA4_UNORM, BGRA, L, VTR_),
- FMT(R16G16B16A16_UNORM, RGBA16_UNORM, RGBA, L, VT__),
- FMT(R32G32B32A32_UNORM, RGBA32_UNORM, RGBA, L, VT__),
+ FMT(R16G16B16A16_UNORM, RGBA16_UNORM, RGBA, L, VTR_),
FMT(B8G8R8A8_UNORM, RGBA8_UNORM, BGRA, L, VTR_),
FMT(B8G8R8X8_UNORM, RGBA8_UNORM, BGR1, L, VTR_),
FMT(A8R8G8B8_UNORM, RGBA8_UNORM, GBAR, L, VTR_),
if (desc->format == PIPE_FORMAT_R11G11B10_FLOAT)
return false;
+ if (desc->is_array) {
+ int c = util_format_get_first_non_void_channel(desc->format);
+ assert(c >= 0);
+ if (desc->channel[c].size > 8)
+ return false;
+ }
+
return true;
}
return nir_vec(b, replicated, 4);
}
-static nir_ssa_def *
-pan_unpack_pure_32(nir_builder *b, nir_ssa_def *pack, unsigned num_components)
-{
- return nir_channels(b, pack, (1 << num_components) - 1);
-}
-
/* Pure x16 formats are x16 unpacked, so it's similar, but we need to pack
* upper/lower halves of course */
return nir_channels(b, unpacked, (1 << num_components) - 1);
}
+static nir_ssa_def *
+pan_fsat(nir_builder *b, nir_ssa_def *v, bool is_signed)
+{
+ if (is_signed)
+ return nir_fsat_signed_mali(b, v);
+ else
+ return nir_fsat(b, v);
+}
+
+static float
+norm_scale(bool snorm, unsigned bits)
+{
+ if (snorm)
+ return (1 << (bits - 1)) - 1;
+ else
+ return (1 << bits) - 1;
+}
+
/* For <= 8-bits per channel, [U,S]NORM formats are packed like [U,S]NORM 8,
* with zeroes spacing out each component as needed */
/* If a channel has N bits, we pad out to the byte by (8 - N) bits */
nir_ssa_def *shifts = nir_imm_ivec4(b, 8 - x, 8 - y, 8 - z, 8 - w);
-
- nir_ssa_def *clamped =
- is_signed ?
- nir_fsat_signed_mali(b, nir_pad_vec4(b, v)) :
- nir_fsat(b, nir_pad_vec4(b, v));
+ nir_ssa_def *clamped = pan_fsat(b, nir_pad_vec4(b, v), is_signed);
nir_ssa_def *f = nir_fmul(b, clamped, scales);
nir_ssa_def *u8 = nir_f2u8(b, nir_fround_even(b, f));
return nir_vec(b, comp, 4);
}
+static nir_ssa_def *
+pan_unpack_pure(nir_builder *b, nir_ssa_def *packed, unsigned size, unsigned nr)
+{
+ switch (size) {
+ case 32:
+ return nir_trim_vector(b, packed, nr);
+ case 16:
+ return pan_unpack_pure_16(b, packed, nr);
+ case 8:
+ return pan_unpack_pure_8(b, packed, nr);
+ default:
+ unreachable("Unrenderable size");
+ }
+}
+
/* Generic dispatches for un/pack regardless of format */
static nir_ssa_def *
int c = util_format_get_first_non_void_channel(desc->format);
assert(c >= 0);
struct util_format_channel_description d = desc->channel[c];
+ nir_ssa_def *unpacked = pan_unpack_pure(b, packed, d.size, desc->nr_channels);
- if (d.size == 32 || d.size == 16) {
- assert(!d.normalized);
- assert(d.type == UTIL_FORMAT_TYPE_FLOAT || d.pure_integer);
+ /* Normalized formats are unpacked as integers. We need to
+ * convert to float for the final result.
+ */
+ if (d.normalized) {
+ bool snorm = desc->is_snorm;
+ unsigned float_sz = (d.size <= 8 ? 16 : 32);
+ float multiplier = norm_scale(snorm, d.size);
- return d.size == 32 ? pan_unpack_pure_32(b, packed, desc->nr_channels) :
- pan_unpack_pure_16(b, packed, desc->nr_channels);
- } else if (d.size == 8) {
- assert(d.pure_integer);
- return pan_unpack_pure_8(b, packed, desc->nr_channels);
+ nir_ssa_def *as_float =
+ snorm ? nir_i2fN(b, unpacked, float_sz) :
+ nir_u2fN(b, unpacked, float_sz);
+
+ return nir_fmul_imm(b, as_float, 1.0 / multiplier);
} else {
- unreachable("Unrenderable size");
+ return unpacked;
}
}
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
unpacked = pan_linear_to_srgb(b, unpacked);
- if (util_format_is_unorm8(desc))
- return pan_pack_unorm(b, unpacked, 8, 8, 8, 8);
-
- if (util_format_is_snorm8(desc->format))
- return pan_pack_snorm(b, unpacked, 8, 8, 8, 8);
-
if (desc->is_array) {
int c = util_format_get_first_non_void_channel(desc->format);
assert(c >= 0);
struct util_format_channel_description d = desc->channel[c];
- if (d.size == 32 || d.size == 16) {
- assert(!d.normalized);
- assert(d.type == UTIL_FORMAT_TYPE_FLOAT || d.pure_integer);
+ /* Pure formats are packed as-is */
+ nir_ssa_def *raw = unpacked;
- return d.size == 32 ?
- pan_replicate(b, unpacked, desc->nr_channels) :
- pan_pack_pure_16(b, unpacked, desc->nr_channels);
- } else if (d.size == 8) {
- assert(d.pure_integer);
- return pan_pack_pure_8(b, unpacked, desc->nr_channels);
- } else {
+ /* Normalized formats get normalized first */
+ if (d.normalized) {
+ bool snorm = desc->is_snorm;
+ float multiplier = norm_scale(snorm, d.size);
+ nir_ssa_def *clamped = pan_fsat(b, unpacked, snorm);
+ nir_ssa_def *normed = nir_fmul_imm(b, clamped, multiplier);
+
+ raw = nir_f2uN(b, normed, d.size);
+ }
+
+ /* Pack the raw format */
+ switch (d.size) {
+ case 32:
+ return pan_replicate(b, raw, desc->nr_channels);
+ case 16:
+ return pan_pack_pure_16(b, raw, desc->nr_channels);
+ case 8:
+ return pan_pack_pure_8(b, raw, desc->nr_channels);
+ default:
unreachable("Unrenderable size");
}
}