From 30ab38ba6d8b78164074569aa1f103c895753090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 4 Sep 2020 13:48:30 -0400 Subject: [PATCH] radeonsi: enable FP16 for mediump on gfx9+ if radeonsi_fp16=true Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- .../drivers/radeonsi/si_debug_options.h | 1 + src/gallium/drivers/radeonsi/si_get.c | 18 +++++++++++++----- src/gallium/drivers/radeonsi/si_pipe.c | 3 ++- src/gallium/drivers/radeonsi/si_shader_nir.c | 4 ++-- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_debug_options.h b/src/gallium/drivers/radeonsi/si_debug_options.h index 11af7e2d594..6131fb3e8f5 100644 --- a/src/gallium/drivers/radeonsi/si_debug_options.h +++ b/src/gallium/drivers/radeonsi/si_debug_options.h @@ -15,5 +15,6 @@ OPT_BOOL(shader_culling, false, "Cull primitives in shaders when benefical (with OPT_BOOL(vrs2x2, false, "Enable 2x2 coarse shading for non-GUI elements") OPT_BOOL(enable_sam, false, "Enable Smart Access Memory with Above 4G Decoding for unvalidated platforms.") OPT_BOOL(disable_sam, false, "Disable Smart Access Memory.") +OPT_BOOL(fp16, false, "Enable FP16 for mediump.") #undef OPT_BOOL diff --git a/src/gallium/drivers/radeonsi/si_get.c b/src/gallium/drivers/radeonsi/si_get.c index db6e75cf062..7578db3f0c4 100644 --- a/src/gallium/drivers/radeonsi/si_get.c +++ b/src/gallium/drivers/radeonsi/si_get.c @@ -27,6 +27,7 @@ #include "radeon/radeon_vce.h" #include "radeon/radeon_video.h" #include "si_pipe.h" +#include "util/u_cpu_detect.h" #include "util/u_screen.h" #include "util/u_video.h" #include "vl/vl_decoder.h" @@ -431,12 +432,17 @@ static int si_get_shader_param(struct pipe_screen *pscreen, enum pipe_shader_typ case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: /* lowered in finalize_nir */ return 1; - /* Unsupported boolean features. */ case PIPE_SHADER_CAP_FP16: case PIPE_SHADER_CAP_FP16_DERIVATIVES: - case PIPE_SHADER_CAP_FP16_CONST_BUFFERS: - case PIPE_SHADER_CAP_INT16: case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS: + return sscreen->options.fp16; + + case PIPE_SHADER_CAP_FP16_CONST_BUFFERS: + /* We need f16c for fast FP16 conversions in glUniform. */ + return sscreen->options.fp16 && util_get_cpu_caps()->has_f16c; + + /* Unsupported boolean features. */ + case PIPE_SHADER_CAP_INT16: case PIPE_SHADER_CAP_SUBROUTINES: case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS: case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS: @@ -925,6 +931,8 @@ static void si_init_renderer_string(struct si_screen *sscreen) void si_init_screen_get_functions(struct si_screen *sscreen) { + util_cpu_detect(); + sscreen->b.get_name = si_get_name; sscreen->b.get_vendor = si_get_vendor; sscreen->b.get_device_vendor = si_get_device_vendor; @@ -997,8 +1005,8 @@ void si_init_screen_get_functions(struct si_screen *sscreen) .max_unroll_iterations = 32, .use_interpolated_input_intrinsics = true, .lower_uniforms_to_ubo = true, - .support_16bit_alu = sscreen->info.has_packed_math_16bit, - .vectorize_vec2_16bit = sscreen->info.has_packed_math_16bit, + .support_16bit_alu = sscreen->options.fp16, + .vectorize_vec2_16bit = sscreen->options.fp16, }; sscreen->nir_options = nir_options; } diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 6037558c213..35bbbb8125d 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -1005,7 +1005,8 @@ static struct pipe_screen *radeonsi_screen_create_impl(struct radeon_winsys *ws, sscreen->options.disable_sam); /* Older LLVM have buggy v_pk_* instructions. */ - sscreen->info.has_packed_math_16bit &= LLVM_VERSION_MAJOR >= 11; + if (!sscreen->info.has_packed_math_16bit || LLVM_VERSION_MAJOR < 11) + sscreen->options.fp16 = false; if (sscreen->info.chip_class == GFX10_3 && LLVM_VERSION_MAJOR < 11) { fprintf(stderr, "radeonsi: GFX 10.3 requires LLVM 11 or higher\n"); diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c b/src/gallium/drivers/radeonsi/si_shader_nir.c index a04a724e263..21576b12410 100644 --- a/src/gallium/drivers/radeonsi/si_shader_nir.c +++ b/src/gallium/drivers/radeonsi/si_shader_nir.c @@ -514,7 +514,7 @@ static bool si_alu_to_scalar_filter(const nir_instr *instr, const void *data) { struct si_screen *sscreen = (struct si_screen *)data; - if (sscreen->info.has_packed_math_16bit && + if (sscreen->options.fp16 && instr->type == nir_instr_type_alu) { nir_alu_instr *alu = nir_instr_as_alu(instr); @@ -594,7 +594,7 @@ void si_nir_opts(struct si_screen *sscreen, struct nir_shader *nir, bool first) NIR_PASS(progress, nir, nir_opt_loop_unroll, 0); } - if (sscreen->info.has_packed_math_16bit) + if (sscreen->options.fp16) NIR_PASS(progress, nir, nir_opt_vectorize, NULL, NULL); } while (progress);