From c6cc3dece03ea8095a2292a2b817f4a34129f320 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 6 Apr 2021 11:24:44 +1000 Subject: [PATCH] llvmpipe: add shader clock support Add support for calling out to the os time functions from the llvm side. Reviewed-by: Mike Blumenkrantz Part-of: --- docs/features.txt | 2 +- docs/relnotes/new_features.txt | 1 + src/gallium/auxiliary/gallivm/lp_bld_init.c | 10 ++++++++++ src/gallium/auxiliary/gallivm/lp_bld_init.h | 3 +++ src/gallium/auxiliary/gallivm/lp_bld_nir.c | 3 +++ src/gallium/auxiliary/gallivm/lp_bld_nir.h | 1 + .../auxiliary/gallivm/lp_bld_nir_soa.c | 20 +++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_screen.c | 1 + 8 files changed, 40 insertions(+), 1 deletion(-) diff --git a/docs/features.txt b/docs/features.txt index c0a883efe42..9a4a4cce1ff 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -307,7 +307,7 @@ Khronos, ARB, and OES extensions that are not part of any OpenGL or OpenGL ES ve GL_ARB_sample_locations DONE (nvc0, zink) GL_ARB_seamless_cubemap_per_texture DONE (etnaviv/SEAMLESS_CUBE_MAP, freedreno, i965, nvc0, r600, radeonsi, softpipe, virgl, zink) GL_ARB_shader_ballot DONE (i965/gen8+, nvc0, radeonsi, zink) - GL_ARB_shader_clock DONE (i965/gen7+, nv50, nvc0, r600, radeonsi, virgl, zink) + GL_ARB_shader_clock DONE (i965/gen7+, nv50, nvc0, r600, radeonsi, llvmpipe, virgl, zink) GL_ARB_shader_stencil_export DONE (i965/gen9+, r600, radeonsi, softpipe, llvmpipe, virgl, panfrost, zink) GL_ARB_shader_viewport_layer_array DONE (i965/gen6+, nvc0, radeonsi, zink) GL_ARB_shading_language_include DONE diff --git a/docs/relnotes/new_features.txt b/docs/relnotes/new_features.txt index e69de29bb2d..446ffefd274 100644 --- a/docs/relnotes/new_features.txt +++ b/docs/relnotes/new_features.txt @@ -0,0 +1 @@ +GL_ARB_shader_clock on llvmpipe diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.c b/src/gallium/auxiliary/gallivm/lp_bld_init.c index ca50a6debbd..9e28256ac53 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_init.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_init.c @@ -569,6 +569,14 @@ gallivm_verify_function(struct gallivm_state *gallivm, } } +void lp_init_clock_hook(struct gallivm_state *gallivm) +{ + if (gallivm->get_time_hook) + return; + + LLVMTypeRef get_time_type = LLVMFunctionType(LLVMInt64TypeInContext(gallivm->context), NULL, 0, 1); + gallivm->get_time_hook = LLVMAddFunction(gallivm->module, "get_time_hook", get_time_type); +} /** * Compile a module. @@ -693,6 +701,8 @@ gallivm_compile_module(struct gallivm_state *gallivm) lp_init_printf_hook(gallivm); LLVMAddGlobalMapping(gallivm->engine, gallivm->debug_printf_hook, debug_printf); + lp_init_clock_hook(gallivm); + LLVMAddGlobalMapping(gallivm->engine, gallivm->get_time_hook, os_time_get_nano); if (gallivm_debug & GALLIVM_DEBUG_ASM) { LLVMValueRef llvm_func = LLVMGetFirstFunction(gallivm->module); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.h b/src/gallium/auxiliary/gallivm/lp_bld_init.h index 81f0a1f31ba..ca267a36f92 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_init.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_init.h @@ -64,6 +64,8 @@ struct gallivm_state LLVMTypeRef coro_malloc_hook_type; LLVMTypeRef coro_free_hook_type; + + LLVMValueRef get_time_hook; }; @@ -94,6 +96,7 @@ gallivm_jit_function(struct gallivm_state *gallivm, unsigned gallivm_get_perf_flags(void); +void lp_init_clock_hook(struct gallivm_state *gallivm); #ifdef __cplusplus } #endif diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir.c b/src/gallium/auxiliary/gallivm/lp_bld_nir.c index 715977672e3..260c796d26d 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir.c @@ -2203,6 +2203,9 @@ visit_intrinsic(struct lp_build_nir_context *bld_base, case nir_intrinsic_store_scratch: visit_store_scratch(bld_base, instr); break; + case nir_intrinsic_shader_clock: + bld_base->clock(bld_base, result); + break; default: fprintf(stderr, "Unsupported intrinsic: "); nir_print_instr(&instr->instr, stderr); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir.h b/src/gallium/auxiliary/gallivm/lp_bld_nir.h index 13236719a1c..055794f7c63 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir.h @@ -222,6 +222,7 @@ struct lp_build_nir_context LLVMValueRef dst[4]); void (*helper_invocation)(struct lp_build_nir_context *bld_base, LLVMValueRef *dst); + void (*clock)(struct lp_build_nir_context *bld_Base, LLVMValueRef dst[4]); void (*interp_at)(struct lp_build_nir_context *bld_base, unsigned num_components, nir_variable *var, diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c index 776e95f25bf..5a92fdbc996 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c @@ -2642,6 +2642,25 @@ emit_store_scratch(struct lp_build_nir_context *bld_base, } } +static void +emit_clock(struct lp_build_nir_context *bld_base, + LLVMValueRef dst[4]) +{ + struct gallivm_state *gallivm = bld_base->base.gallivm; + LLVMBuilderRef builder = gallivm->builder; + struct lp_build_context *uint_bld = get_int_bld(bld_base, true, 32); + + lp_init_clock_hook(gallivm); + + LLVMValueRef result = LLVMBuildCall(builder, gallivm->get_time_hook, NULL, 0, ""); + + LLVMValueRef hi = LLVMBuildShl(builder, result, lp_build_const_int64(gallivm, 32), ""); + hi = LLVMBuildTrunc(builder, hi, uint_bld->elem_type, ""); + LLVMValueRef lo = LLVMBuildTrunc(builder, result, uint_bld->elem_type, ""); + dst[0] = lp_build_broadcast_scalar(uint_bld, lo); + dst[1] = lp_build_broadcast_scalar(uint_bld, hi); +} + void lp_build_nir_soa(struct gallivm_state *gallivm, struct nir_shader *shader, const struct lp_build_tgsi_params *params, @@ -2755,6 +2774,7 @@ void lp_build_nir_soa(struct gallivm_state *gallivm, bld.bld_base.load_scratch = emit_load_scratch; bld.bld_base.store_scratch = emit_store_scratch; bld.bld_base.load_const = emit_load_const; + bld.bld_base.clock = emit_clock; bld.mask = params->mask; bld.inputs = params->inputs; diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index ebaa8326697..f1667fe1cfa 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -361,6 +361,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_SAMPLE_SHADING: case PIPE_CAP_GL_SPIRV: case PIPE_CAP_POST_DEPTH_COVERAGE: + case PIPE_CAP_SHADER_CLOCK: case PIPE_CAP_PACKED_UNIFORMS: { struct llvmpipe_screen *lscreen = llvmpipe_screen(screen); return !lscreen->use_tgsi;