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. --- src/mesa/drivers/dri/i965/brw_ir_surface_builder.h | 125 +++++++++++++++++++++ 1 file changed, 125 insertions(+)
diff --git a/src/mesa/drivers/dri/i965/brw_ir_surface_builder.h b/src/mesa/drivers/dri/i965/brw_ir_surface_builder.h index 317ad15..b132f99 100644 --- a/src/mesa/drivers/dri/i965/brw_ir_surface_builder.h +++ b/src/mesa/drivers/dri/i965/brw_ir_surface_builder.h @@ -1104,6 +1104,131 @@ namespace brw { return dst; } } + + namespace image_format_info { + using detail::color; + + /** + * Return the per-channel bitfield widths for a given image format. + */ + inline color<unsigned> + get_bit_widths(mesa_format format) + { + return color<unsigned>(_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<unsigned> + get_bit_shifts(mesa_format format) + { + const color<unsigned> widths = get_bit_widths(format); + return color<unsigned>(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<unsigned> 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<unsigned> widths = get_bit_widths(format); + const color<unsigned> 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 -- 2.3.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev