diff options
author | Sagar Ghuge <[email protected]> | 2019-02-27 14:02:54 -0800 |
---|---|---|
committer | Sagar Ghuge <[email protected]> | 2019-03-04 15:50:25 -0800 |
commit | 1d8994a63b546a5b2dc4feb5bd98a84ee853d6af (patch) | |
tree | 6ff1fb8b5cca7261fb887e3bc9dfe773121e2352 /src/compiler/glsl/builtin_functions.cpp | |
parent | e551040c602d392019e68f54d9a3a310d2a937a3 (diff) |
glsl: [u/i]mulExtended optimization for GLSL
Optimize mulExtended to use 32x32->64 multiplication.
Drivers which are not based on NIR, they can set the
MUL64_TO_MUL_AND_MUL_HIGH lowering flag in order to have same old
behavior.
v2: Add missing condition check (Jason Ekstrand)
Signed-off-by: Sagar Ghuge <[email protected]>
Suggested-by: Matt Turner <Matt Turner <[email protected]>
Suggested-by: Jason Ekstrand <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src/compiler/glsl/builtin_functions.cpp')
-rw-r--r-- | src/compiler/glsl/builtin_functions.cpp | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp index aba1a14bd90..386cbc0ccd7 100644 --- a/src/compiler/glsl/builtin_functions.cpp +++ b/src/compiler/glsl/builtin_functions.cpp @@ -5866,14 +5866,42 @@ builtin_builder::_usubBorrow(const glsl_type *type) ir_function_signature * builtin_builder::_mulExtended(const glsl_type *type) { + const glsl_type *mul_type, *unpack_type; + ir_expression_operation unpack_op; + + if (type->base_type == GLSL_TYPE_INT) { + unpack_op = ir_unop_unpack_int_2x32; + mul_type = glsl_type::get_instance(GLSL_TYPE_INT64, type->vector_elements, 1); + unpack_type = glsl_type::ivec2_type; + } else { + unpack_op = ir_unop_unpack_uint_2x32; + mul_type = glsl_type::get_instance(GLSL_TYPE_UINT64, type->vector_elements, 1); + unpack_type = glsl_type::uvec2_type; + } + ir_variable *x = in_var(type, "x"); ir_variable *y = in_var(type, "y"); ir_variable *msb = out_var(type, "msb"); ir_variable *lsb = out_var(type, "lsb"); MAKE_SIG(glsl_type::void_type, gpu_shader5_or_es31_or_integer_functions, 4, x, y, msb, lsb); - body.emit(assign(msb, imul_high(x, y))); - body.emit(assign(lsb, mul(x, y))); + ir_variable *unpack_val = body.make_temp(unpack_type, "_unpack_val"); + + ir_expression *mul_res = new(mem_ctx) ir_expression(ir_binop_mul, mul_type, + new(mem_ctx)ir_dereference_variable(x), + new(mem_ctx)ir_dereference_variable(y)); + + if (type->vector_elements == 1) { + body.emit(assign(unpack_val, expr(unpack_op, mul_res))); + body.emit(assign(msb, swizzle_y(unpack_val))); + body.emit(assign(lsb, swizzle_x(unpack_val))); + } else { + for (int i = 0; i < type->vector_elements; i++) { + body.emit(assign(unpack_val, expr(unpack_op, swizzle(mul_res, i, 1)))); + body.emit(assign(array_ref(msb, i), swizzle_y(unpack_val))); + body.emit(assign(array_ref(lsb, i), swizzle_x(unpack_val))); + } + } return sig; } |