#include "nir_lower_blend.h"
#include "util/u_format.h"
+/* Determines the best NIR intrinsic to load a tile buffer of a given type,
+ * using native format conversion where possible. RGBA8 UNORM has a fast path
+ * (on some chips). Otherwise, we default to raw reads. */
+
+static nir_intrinsic_op
+nir_best_load_for_format(
+ const struct util_format_description *desc,
+ unsigned *special_bitsize,
+ unsigned gpu_id)
+{
+ if (util_format_is_unorm8(desc) && gpu_id != 0x750) {
+ *special_bitsize = 16;
+ return nir_intrinsic_load_output_u8_as_fp16_pan;
+ } else
+ return nir_intrinsic_load_raw_output_pan;
+}
+
+
/* Converters for UNORM8 formats, e.g. R8G8B8A8_UNORM */
static nir_ssa_def *
static nir_ssa_def *
nir_native_to_shader(nir_builder *b,
nir_ssa_def *c_native,
+ nir_intrinsic_op op,
const struct util_format_description *desc,
unsigned bits,
bool homogenous_bits)
util_format_is_float(desc->format) ||
util_format_is_pure_integer(desc->format);
+ /* Handle preconverted formats */
+ if (op == nir_intrinsic_load_output_u8_as_fp16_pan) {
+ assert(util_format_is_unorm8(desc));
+ return nir_f2f32(b, c_native);
+ }
+
+ /* Otherwise, we're raw */
+ assert(op == nir_intrinsic_load_raw_output_pan);
+
if (util_format_is_unorm8(desc))
return nir_unorm8_to_float(b, c_native);
else if (homogenous_bits && float_or_pure_int)
}
void
-nir_lower_framebuffer(nir_shader *shader, enum pipe_format format)
+nir_lower_framebuffer(nir_shader *shader, enum pipe_format format,
+ unsigned gpu_id)
{
/* Blend shaders are represented as special fragment shaders */
assert(shader->info.stage == MESA_SHADER_FRAGMENT);
/* For loads, add conversion after */
b.cursor = nir_after_instr(instr);
- /* Rewrite to use a native load by creating a new intrinsic */
-
- nir_intrinsic_instr *new =
- nir_intrinsic_instr_create(shader, nir_intrinsic_load_raw_output_pan);
+ /* Determine the best op for the format/hardware */
+ unsigned bitsize = raw_bitsize_in;
+ nir_intrinsic_op op = nir_best_load_for_format(format_desc,
+ &bitsize,
+ gpu_id);
+ /* Rewrite to use a native load by creating a new intrinsic */
+ nir_intrinsic_instr *new = nir_intrinsic_instr_create(shader, op);
new->num_components = 4;
- unsigned bitsize = raw_bitsize_in;
nir_ssa_dest_init(&new->instr, &new->dest, 4, bitsize, NULL);
nir_builder_instr_insert(&b, &new->instr);
/* Convert the raw value */
nir_ssa_def *raw = &new->dest.ssa;
- nir_ssa_def *converted = nir_native_to_shader(&b, raw, format_desc, bits, homogenous_bits);
+ nir_ssa_def *converted = nir_native_to_shader(&b, raw, op, format_desc, bits, homogenous_bits);
/* Rewrite to use the converted value */
nir_src rewritten = nir_src_for_ssa(converted);