summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2015-04-22 16:45:28 +0300
committerFrancisco Jerez <currojerez@riseup.net>2015-05-12 17:47:27 +0300
commit373b6ba4b578302780da567bd02a6fc723513f9e (patch)
tree449e5a2eeea7d145af558876e3ac62610c1104e3
parent1d011f2328f806acb4725fdc5dfcf7aa12ab94a3 (diff)
i965/fs: Import image format metadata queries.
Define some utility functions to query the bitfield layout of a given image format and whether it satisfies a number of more or less hardware-specific properties. v2: Drop VEC4 suport.
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_surface_builder.h147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_surface_builder.h b/src/mesa/drivers/dri/i965/brw_fs_surface_builder.h
index 264314b7724..e3cceeb478a 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_surface_builder.h
+++ b/src/mesa/drivers/dri/i965/brw_fs_surface_builder.h
@@ -65,5 +65,152 @@ namespace brw {
unsigned dims, unsigned rsize, unsigned op,
brw_predicate pred = BRW_PREDICATE_NONE);
}
+
+ namespace image_format_info {
+ /**
+ * Simple 4-tuple of scalars used to pass around per-color component
+ * values.
+ */
+ struct color_u {
+ color_u(unsigned x = 0) : r(x), g(x), b(x), a(x)
+ {
+ }
+
+ color_u(unsigned r, unsigned g, unsigned b, unsigned a) :
+ r(r), g(g), b(b), a(a)
+ {
+ }
+
+ unsigned
+ operator[](unsigned i) const
+ {
+ const unsigned xs[] = { r, g, b, a };
+ return xs[i];
+ }
+
+ unsigned r, g, b, a;
+ };
+
+ /**
+ * Return the per-channel bitfield widths for a given image format.
+ */
+ inline color_u
+ get_bit_widths(mesa_format format)
+ {
+ return color_u(_mesa_get_format_bits(format, GL_RED_BITS),
+ _mesa_get_format_bits(format, GL_GREEN_BITS),
+ _mesa_get_format_bits(format, GL_BLUE_BITS),
+ _mesa_get_format_bits(format, GL_ALPHA_BITS));
+ }
+
+ /**
+ * Return the per-channel bitfield shifts for a given image format.
+ */
+ inline color_u
+ get_bit_shifts(mesa_format format)
+ {
+ const color_u widths = get_bit_widths(format);
+ return color_u(0, widths.r, widths.r + widths.g,
+ widths.r + widths.g + widths.b);
+ }
+
+ /**
+ * Return true if all present components have the same bit width.
+ */
+ inline bool
+ is_homogeneous(mesa_format format)
+ {
+ const color_u widths = get_bit_widths(format);
+ return ((widths.g == 0 || widths.g == widths.r) &&
+ (widths.b == 0 || widths.b == widths.r) &&
+ (widths.a == 0 || widths.a == widths.r));
+ }
+
+ /**
+ * Return true if the format conversion boils down to a trivial copy.
+ */
+ inline bool
+ is_conversion_trivial(const brw_device_info *devinfo, mesa_format format)
+ {
+ return (get_bit_widths(format).r == 32 && is_homogeneous(format)) ||
+ format == brw_lower_mesa_image_format(devinfo, format);
+ }
+
+ /**
+ * Return true if the hardware natively supports some format with
+ * compatible bitfield layout, but possibly different data types.
+ */
+ inline bool
+ has_supported_bit_layout(const brw_device_info *devinfo,
+ mesa_format format)
+ {
+ const color_u widths = get_bit_widths(format);
+ const color_u lower_widths = get_bit_widths(
+ brw_lower_mesa_image_format(devinfo, format));
+
+ return (widths.r == lower_widths.r &&
+ widths.g == lower_widths.g &&
+ widths.b == lower_widths.b &&
+ widths.a == lower_widths.a);
+ }
+
+ /**
+ * Return true if we are required to spread individual components over
+ * several components of the format used by the hardware (RG32 and
+ * friends implemented as RGBA16UI).
+ */
+ inline bool
+ has_split_bit_layout(const brw_device_info *devinfo, mesa_format format)
+ {
+ const mesa_format lower_format =
+ brw_lower_mesa_image_format(devinfo, format);
+
+ return (_mesa_format_num_components(format) <
+ _mesa_format_num_components(lower_format));
+ }
+
+ /**
+ * Return true unless we have to fall back to untyped surface access.
+ * Fail!
+ */
+ inline bool
+ has_matching_typed_format(const brw_device_info *devinfo,
+ mesa_format format)
+ {
+ return (_mesa_get_format_bytes(format) <= 4 ||
+ (_mesa_get_format_bytes(format) <= 8 &&
+ (devinfo->gen >= 8 || devinfo->is_haswell)));
+ }
+
+ /**
+ * Return true if the hardware returns garbage in the unused high bits
+ * of each component. This may happen on IVB because we rely on the
+ * undocumented behavior that typed reads from surfaces of the
+ * unsupported R8 and R16 formats return useful data in their least
+ * significant bits.
+ */
+ inline bool
+ has_undefined_high_bits(const brw_device_info *devinfo,
+ mesa_format format)
+ {
+ const mesa_format lower_format =
+ brw_lower_mesa_image_format(devinfo, format);
+
+ return (devinfo->gen == 7 && !devinfo->is_haswell &&
+ (lower_format == MESA_FORMAT_R_UINT16 ||
+ lower_format == MESA_FORMAT_R_UINT8));
+ }
+
+ /**
+ * Return true if the format represents values as signed integers
+ * requiring sign extension when unpacking.
+ */
+ inline bool
+ needs_sign_extension(mesa_format format)
+ {
+ return (_mesa_get_format_datatype(format) == GL_SIGNED_NORMALIZED ||
+ _mesa_get_format_datatype(format) == GL_INT);
+ }
+ }
}
#endif