[Mesa-dev] [PATCH 19/47] glsl: Add a lowering pass for 64-bit float abs()
Elie Tournier
tournier.elie at gmail.com
Wed Aug 23 11:07:49 UTC 2017
Squashed with:
glsl/lower_64bit: fix return type conversion (airlied)
Only do conversion for the 64-bit types, add a path
to do result merging without conversion.
Signed-off-by: Elie Tournier <elie.tournier at collabora.com>
---
src/compiler/Makefile.sources | 2 +-
src/compiler/glsl/ir_optimization.h | 8 +-
.../glsl/{lower_int64.cpp => lower_64bit.cpp} | 87 ++++++++++++++++++----
src/mesa/state_tracker/st_extensions.c | 3 +-
src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 9 +++
5 files changed, 92 insertions(+), 17 deletions(-)
rename src/compiler/glsl/{lower_int64.cpp => lower_64bit.cpp} (81%)
diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources
index 24fa7716de..699133234c 100644
--- a/src/compiler/Makefile.sources
+++ b/src/compiler/Makefile.sources
@@ -92,7 +92,7 @@ LIBGLSL_FILES = \
glsl/lower_distance.cpp \
glsl/lower_if_to_cond_assign.cpp \
glsl/lower_instructions.cpp \
- glsl/lower_int64.cpp \
+ glsl/lower_64bit.cpp \
glsl/lower_jumps.cpp \
glsl/lower_mat_op_to_vec.cpp \
glsl/lower_noise.cpp \
diff --git a/src/compiler/glsl/ir_optimization.h b/src/compiler/glsl/ir_optimization.h
index 573ddb4a8d..6cc0909a80 100644
--- a/src/compiler/glsl/ir_optimization.h
+++ b/src/compiler/glsl/ir_optimization.h
@@ -55,11 +55,14 @@
#define DIV_TO_MUL_RCP (FDIV_TO_MUL_RCP | DDIV_TO_MUL_RCP)
#define SQRT_TO_ABS_SQRT 0x200000
-/* Opertaions for lower_64bit_integer_instructions() */
+/* Operations for lower_64bit_integer_instructions()
+ * and lower_64bit_double_instructions()
+ */
#define MUL64 (1U << 0)
#define SIGN64 (1U << 1)
#define DIV64 (1U << 2)
#define MOD64 (1U << 3)
+#define ABS64 (1U << 4)
/**
* \see class lower_packing_builtins_visitor
@@ -177,4 +180,7 @@ compare_index_block(exec_list *instructions, ir_variable *index,
bool lower_64bit_integer_instructions(exec_list *instructions,
unsigned what_to_lower);
+bool lower_64bit_double_instructions(exec_list *instructions,
+ unsigned what_to_lower);
+
#endif /* GLSL_IR_OPTIMIZATION_H */
diff --git a/src/compiler/glsl/lower_int64.cpp b/src/compiler/glsl/lower_64bit.cpp
similarity index 81%
rename from src/compiler/glsl/lower_int64.cpp
rename to src/compiler/glsl/lower_64bit.cpp
index 2d4fdbb1a5..4887e5538c 100644
--- a/src/compiler/glsl/lower_int64.cpp
+++ b/src/compiler/glsl/lower_64bit.cpp
@@ -22,7 +22,7 @@
*/
/**
- * \file lower_int64.cpp
+ * \file lower_64bit.cpp
*
* Lower 64-bit operations to 32-bit operations. Each 64-bit value is lowered
* to a uvec2. For each operation that can be lowered, there is a function
@@ -56,6 +56,9 @@ void expand_source(ir_factory &, ir_rvalue *val, ir_variable **expanded_src);
ir_dereference_variable *compact_destination(ir_factory &,
const glsl_type *type,
ir_variable *result[4]);
+ir_dereference_variable *merge_destination(ir_factory &,
+ const glsl_type *type,
+ ir_variable *result[4]);
ir_rvalue *lower_op_to_function_call(ir_instruction *base_ir,
ir_expression *ir,
@@ -132,7 +135,7 @@ private:
#define lowering(x) (this->lower & x)
bool
-lower_64bit_integer_instructions(exec_list *instructions,
+lower_64bit_instructions(exec_list *instructions,
unsigned what_to_lower)
{
if (instructions->is_empty())
@@ -163,6 +166,19 @@ lower_64bit_integer_instructions(exec_list *instructions,
return v.progress;
}
+bool
+lower_64bit_integer_instructions(exec_list *instructions,
+ unsigned what_to_lower)
+{
+ return lower_64bit_instructions(instructions, what_to_lower);
+}
+
+bool
+lower_64bit_double_instructions(exec_list *instructions,
+ unsigned what_to_lower)
+{
+ return lower_64bit_instructions(instructions, what_to_lower);
+}
/**
* Expand individual 64-bit values to uvec2 values
@@ -200,18 +216,21 @@ lower_64bit::expand_source(ir_factory &body,
ir_rvalue *val,
ir_variable **expanded_src)
{
- assert(val->type->is_integer_64());
+ assert(val->type->is_integer_64() || val->type->is_double());
ir_variable *const temp = body.make_temp(val->type, "tmp");
body.emit(assign(temp, val));
const ir_expression_operation unpack_opcode =
- val->type->base_type == GLSL_TYPE_UINT64
- ? ir_unop_unpack_uint_2x32 : ir_unop_unpack_int_2x32;
+ val->type->base_type == GLSL_TYPE_DOUBLE
+ ? ir_unop_unpack_double_2x32 :
+ (val->type->base_type == GLSL_TYPE_UINT64
+ ? ir_unop_unpack_uint_2x32 : ir_unop_unpack_int_2x32);
const glsl_type *const type =
- val->type->base_type == GLSL_TYPE_UINT64
+ (val->type->base_type == GLSL_TYPE_UINT64 ||
+ val->type->base_type == GLSL_TYPE_DOUBLE)
? glsl_type::uvec2_type : glsl_type::ivec2_type;
unsigned i;
@@ -235,8 +254,10 @@ lower_64bit::compact_destination(ir_factory &body,
ir_variable *result[4])
{
const ir_expression_operation pack_opcode =
- type->base_type == GLSL_TYPE_UINT64
- ? ir_unop_pack_uint_2x32 : ir_unop_pack_int_2x32;
+ type->base_type == GLSL_TYPE_DOUBLE
+ ? ir_unop_pack_double_2x32 :
+ (type->base_type == GLSL_TYPE_UINT64
+ ? ir_unop_pack_uint_2x32 : ir_unop_pack_int_2x32);
ir_variable *const compacted_result =
body.make_temp(type, "compacted_64bit_result");
@@ -251,6 +272,24 @@ lower_64bit::compact_destination(ir_factory &body,
return new(mem_ctx) ir_dereference_variable(compacted_result);
}
+ir_dereference_variable *
+lower_64bit::merge_destination(ir_factory &body,
+ const glsl_type *type,
+ ir_variable *result[4])
+{
+ ir_variable *const merged_result =
+ body.make_temp(type, "merged_result");
+
+ for (unsigned i = 0; i < type->vector_elements; i++) {
+ body.emit(assign(merged_result,
+ result[i],
+ 1U << i));
+ }
+
+ void *const mem_ctx = ralloc_parent(merged_result);
+ return new(mem_ctx) ir_dereference_variable(merged_result);
+}
+
ir_rvalue *
lower_64bit::lower_op_to_function_call(ir_instruction *base_ir,
ir_expression *ir,
@@ -262,9 +301,16 @@ lower_64bit::lower_op_to_function_call(ir_instruction *base_ir,
void *const mem_ctx = ralloc_parent(ir);
exec_list instructions;
unsigned source_components = 0;
- const glsl_type *const result_type =
- ir->type->base_type == GLSL_TYPE_UINT64
- ? glsl_type::uvec2_type : glsl_type::ivec2_type;
+ const glsl_type *result_type;
+
+ if (ir->type->is_64bit()) {
+ if (ir->type->base_type == GLSL_TYPE_UINT64 ||
+ ir->type->base_type == GLSL_TYPE_DOUBLE)
+ result_type = glsl_type::uvec2_type;
+ else
+ result_type = glsl_type::ivec2_type;
+ } else
+ result_type = ir->type->get_scalar_type();
ir_factory body(&instructions, mem_ctx);
@@ -293,7 +339,11 @@ lower_64bit::lower_op_to_function_call(ir_instruction *base_ir,
body.emit(c);
}
- ir_rvalue *const rv = compact_destination(body, ir->type, dst);
+ ir_rvalue *rv;
+ if (ir->type->is_64bit())
+ rv = compact_destination(body, ir->type, dst);
+ else
+ rv = merge_destination(body, ir->type, dst);
/* Move all of the nodes from instructions between base_ir and the
* instruction before it.
@@ -317,8 +367,9 @@ lower_64bit_visitor::handle_op(ir_expression *ir,
const char *function_name,
function_generator generator)
{
- for (unsigned i = 0; i < ir->num_operands; i++)
- if (!ir->operands[i]->type->is_integer_64())
+ for (unsigned i = 0; i < ir->get_num_operands(); i++)
+ if (!ir->operands[i]->type->is_integer_64() &&
+ !ir->operands[i]->type->is_double())
return ir;
/* Get a handle to the correct ir_function_signature for the core
@@ -353,6 +404,14 @@ lower_64bit_visitor::handle_rvalue(ir_rvalue **rvalue)
assert(ir != NULL);
switch (ir->operation) {
+
+ case ir_unop_abs:
+ if (lowering(ABS64)) {
+ if (ir->type->base_type == GLSL_TYPE_DOUBLE)
+ *rvalue = handle_op(ir, "__builtin_fabs64", generate_ir::fabs64);
+ }
+ break;
+
case ir_unop_sign:
if (lowering(SIGN64)) {
*rvalue = handle_op(ir, "__builtin_sign64", generate_ir::sign64);
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index e37814412a..903ea827f7 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -1186,7 +1186,8 @@ void st_init_extensions(struct pipe_screen *screen,
}
#endif
- if (screen->get_param(screen, PIPE_CAP_DOUBLES)) {
+ if (screen->get_param(screen, PIPE_CAP_DOUBLES) ||
+ consts->GLSLVersion >= 130) {
extensions->ARB_gpu_shader_fp64 = GL_TRUE;
extensions->ARB_vertex_attrib_64bit = GL_TRUE;
}
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index d12434101f..991eae4917 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -7053,6 +7053,15 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
if (!pscreen->get_param(pscreen, PIPE_CAP_INT64_DIVMOD))
lower_64bit_integer_instructions(ir, DIV64 | MOD64);
+ /* Enable double lowering if the hardware doesn't support doubles.
+ * The lowering requires GLSL >= 130.
+ */
+ if (!pscreen->get_param(pscreen, PIPE_CAP_DOUBLES) &&
+ ctx->Const.GLSLVersion >= 130) {
+ unsigned lower_inst = ABS64;
+ lower_64bit_double_instructions(ir, lower_inst);
+ }
+
if (ctx->Extensions.ARB_shading_language_packing) {
unsigned lower_inst = LOWER_PACK_SNORM_2x16 |
LOWER_UNPACK_SNORM_2x16 |
--
2.14.1
More information about the mesa-dev
mailing list