[Mesa-dev] [PATCH 25/50] glsl: Add "built-in" functions to do 64x64 => 64 multiplication

Matt Turner mattst88 at gmail.com
Wed Nov 30 20:19:29 UTC 2016


On 11/28, Ian Romanick wrote:
>From: Ian Romanick <ian.d.romanick at intel.com>
>
>These functions are directly available in shaders.  A #define is added
>to detect the presence.  This allows these functions to be tested using
>piglit regardless of whether the driver uses them for lowering.  The
>GLSL spec says that functions and macros beginning with __ are reserved
>for use by the implementation... hey, that's us!
>
>Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
>---
> src/compiler/Makefile.sources           |  2 ++
> src/compiler/glsl/builtin_functions.cpp |  9 +++++++++
> src/compiler/glsl/builtin_functions.h   |  7 +++++++
> src/compiler/glsl/builtin_int64.h       | 30 ++++++++++++++++++++++++++++++
> src/compiler/glsl/generate_ir.cpp       | 33 +++++++++++++++++++++++++++++++++
> src/compiler/glsl/glcpp/glcpp-parse.y   | 14 +++++++++++++-
> src/compiler/glsl/glcpp/glcpp.h         |  4 +++-
> src/compiler/glsl/glcpp/pp.c            |  2 +-
> src/compiler/glsl/int64.glsl            | 19 +++++++++++++++++++
> 9 files changed, 117 insertions(+), 3 deletions(-)
> create mode 100644 src/compiler/glsl/builtin_int64.h
> create mode 100644 src/compiler/glsl/generate_ir.cpp
> create mode 100644 src/compiler/glsl/int64.glsl
>
>diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources
>index 51d7285..31c4f6a 100644
>--- a/src/compiler/Makefile.sources
>+++ b/src/compiler/Makefile.sources
>@@ -21,8 +21,10 @@ LIBGLSL_FILES = \
> 	glsl/blob.h \
> 	glsl/builtin_functions.cpp \
> 	glsl/builtin_functions.h \
>+	glsl/builtin_int64.h \
> 	glsl/builtin_types.cpp \
> 	glsl/builtin_variables.cpp \
>+	glsl/generate_ir.cpp \
> 	glsl/glsl_parser_extras.cpp \
> 	glsl/glsl_parser_extras.h \
> 	glsl/glsl_symbol_table.cpp \
>diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp
>index 66c0a74..4f1a874 100644
>--- a/src/compiler/glsl/builtin_functions.cpp
>+++ b/src/compiler/glsl/builtin_functions.cpp
>@@ -576,6 +576,11 @@ vote(const _mesa_glsl_parse_state *state)
>    return state->ARB_shader_group_vote_enable;
> }
>
>+static bool
>+integer_functions_supported(const _mesa_glsl_parse_state *state)
>+{
>+   return state->extensions->MESA_shader_integer_functions;
>+}
> /** @} */
>
> /******************************************************************************/
>@@ -3103,6 +3108,10 @@ builtin_builder::create_builtins()
>    add_function("allInvocationsARB", _vote(ir_unop_vote_all), NULL);
>    add_function("allInvocationsEqualARB", _vote(ir_unop_vote_eq), NULL);
>
>+   add_function("__builtin_umul64",
>+                generate_ir::umul64(mem_ctx, integer_functions_supported),
>+                NULL);
>+
> #undef F
> #undef FI
> #undef FIUD
>diff --git a/src/compiler/glsl/builtin_functions.h b/src/compiler/glsl/builtin_functions.h
>index 747b4fb..a79fb97 100644
>--- a/src/compiler/glsl/builtin_functions.h
>+++ b/src/compiler/glsl/builtin_functions.h
>@@ -43,4 +43,11 @@ _mesa_get_main_function_signature(glsl_symbol_table *symbols);
> extern void
> _mesa_glsl_release_builtin_functions(void);
>
>+namespace generate_ir {
>+
>+ir_function_signature *
>+umul64(void *mem_ctx, builtin_available_predicate avail);
>+
>+}
>+
> #endif /* BULITIN_FUNCTIONS_H */
>diff --git a/src/compiler/glsl/builtin_int64.h b/src/compiler/glsl/builtin_int64.h
>new file mode 100644
>index 0000000..108da08
>--- /dev/null
>+++ b/src/compiler/glsl/builtin_int64.h
>@@ -0,0 +1,30 @@
>+ir_function_signature *
>+umul64(void *mem_ctx, builtin_available_predicate avail)
>+{
>+   ir_function_signature *const sig =
>+      new(mem_ctx) ir_function_signature(glsl_type::uvec2_type, avail);
>+   ir_factory body(&sig->body, mem_ctx);
>+   sig->is_defined = true;
>+
>+   exec_list sig_parameters;
>+
>+   ir_variable *const r0001 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "a", ir_var_function_in);
>+   sig_parameters.push_tail(r0001);
>+   ir_variable *const r0002 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "b", ir_var_function_in);
>+   sig_parameters.push_tail(r0002);
>+   ir_variable *const r0003 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "result", ir_var_auto);
>+   body.emit(r0003);
>+   body.emit(assign(r0003, imul_high(swizzle_x(r0001), swizzle_x(r0002)), 0x02));
>+
>+   body.emit(assign(r0003, mul(swizzle_x(r0001), swizzle_x(r0002)), 0x01));
>+
>+   ir_expression *const r0004 = mul(swizzle_x(r0001), swizzle_y(r0002));
>+   ir_expression *const r0005 = mul(swizzle_y(r0001), swizzle_x(r0002));
>+   ir_expression *const r0006 = add(r0004, r0005);
>+   body.emit(assign(r0003, add(swizzle_y(r0003), r0006), 0x02));
>+
>+   body.emit(ret(r0003));
>+
>+   sig->replace_parameters(&sig_parameters);
>+   return sig;
>+}
>diff --git a/src/compiler/glsl/generate_ir.cpp b/src/compiler/glsl/generate_ir.cpp
>new file mode 100644
>index 0000000..255b048
>--- /dev/null
>+++ b/src/compiler/glsl/generate_ir.cpp
>@@ -0,0 +1,33 @@
>+/*
>+ * Copyright © 2016 Intel Corporation
>+ *
>+ * Permission is hereby granted, free of charge, to any person obtaining a
>+ * copy of this software and associated documentation files (the "Software"),
>+ * to deal in the Software without restriction, including without limitation
>+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
>+ * and/or sell copies of the Software, and to permit persons to whom the
>+ * Software is furnished to do so, subject to the following conditions:
>+ *
>+ * The above copyright notice and this permission notice (including the next
>+ * paragraph) shall be included in all copies or substantial portions of the
>+ * Software.
>+ *
>+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
>+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
>+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
>+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
>+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
>+ * DEALINGS IN THE SOFTWARE.
>+ */
>+#include "ir_builder.h"
>+#include "builtin_functions.h"
>+#include "program/prog_instruction.h" /* for SWIZZLE_X, &c. */
>+
>+using namespace ir_builder;
>+
>+namespace generate_ir {
>+
>+#include "builtin_int64.h"
>+
>+}
>diff --git a/src/compiler/glsl/glcpp/glcpp-parse.y b/src/compiler/glsl/glcpp/glcpp-parse.y
>index 63012bc..ee55377 100644
>--- a/src/compiler/glsl/glcpp/glcpp-parse.y
>+++ b/src/compiler/glsl/glcpp/glcpp-parse.y
>@@ -1334,7 +1334,8 @@ add_builtin_define(glcpp_parser_t *parser, const char *name, int value)
> }
>
> glcpp_parser_t *
>-glcpp_parser_create(glcpp_extension_iterator extensions, void *state, gl_api api)
>+glcpp_parser_create(const struct gl_extensions *extension_list,
>+                    glcpp_extension_iterator extensions, void *state, gl_api api)
> {
>    glcpp_parser_t *parser;
>
>@@ -1369,6 +1370,7 @@ glcpp_parser_create(glcpp_extension_iterator extensions, void *state, gl_api api
>    parser->error = 0;
>
>    parser->extensions = extensions;
>+   parser->extension_list = extension_list;
>    parser->state = state;
>    parser->api = api;
>    parser->version = 0;
>@@ -2335,6 +2337,16 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio
>       parser->extensions(parser->state, add_builtin_define, parser,
>                          version, parser->is_gles);
>
>+   if (parser->extension_list) {
>+      /* If MESA_shader_integer_functions is supported, then the building
>+       * blocks required for the 64x64 => 64 multiply exist.  Add defines for
>+       * those functions so that they can be tested.
>+       */
>+      if (parser->extension_list->MESA_shader_integer_functions) {
>+         add_builtin_define(parser, "__have_builtin_builtin_umul64", 1);

Just FYI, Clang has a similar mechanism called __has_builtin(x). It
might be nice to match that, but not a big deal either way.

http://clang.llvm.org/docs/LanguageExtensions.html#feature-checking-macros

>+      }
>+   }
>+
>    if (explicitly_set) {
>       ralloc_asprintf_rewrite_tail(&parser->output, &parser->output_length,
>                                    "#version %" PRIiMAX "%s%s", version,
>diff --git a/src/compiler/glsl/glcpp/glcpp.h b/src/compiler/glsl/glcpp/glcpp.h
>index 232e053..2804636 100644
>--- a/src/compiler/glsl/glcpp/glcpp.h
>+++ b/src/compiler/glsl/glcpp/glcpp.h
>@@ -205,6 +205,7 @@ struct glcpp_parser {
> 	size_t info_log_length;
> 	int error;
> 	glcpp_extension_iterator extensions;
>+	const struct gl_extensions *extension_list;
> 	void *state;
> 	gl_api api;
> 	unsigned version;
>@@ -225,7 +226,8 @@ struct glcpp_parser {
> };
>
> glcpp_parser_t *
>-glcpp_parser_create (glcpp_extension_iterator extensions, void *state, gl_api api);
>+glcpp_parser_create(const struct gl_extensions *extension_list,
>+                    glcpp_extension_iterator extensions, void *state, gl_api api);
>
> int
> glcpp_parser_parse (glcpp_parser_t *parser);
>diff --git a/src/compiler/glsl/glcpp/pp.c b/src/compiler/glsl/glcpp/pp.c
>index b591279..c526f37 100644
>--- a/src/compiler/glsl/glcpp/pp.c
>+++ b/src/compiler/glsl/glcpp/pp.c
>@@ -218,7 +218,7 @@ glcpp_preprocess(void *ralloc_ctx, const char **shader, char **info_log,
> {
> 	int errors;
> 	glcpp_parser_t *parser =
>-		glcpp_parser_create(extensions, state, gl_ctx->API);
>+		glcpp_parser_create(&gl_ctx->Extensions, extensions, state, gl_ctx->API);
>
> 	if (! gl_ctx->Const.DisableGLSLLineContinuations)
> 		*shader = remove_line_continuations(parser, *shader);
>diff --git a/src/compiler/glsl/int64.glsl b/src/compiler/glsl/int64.glsl
>new file mode 100644
>index 0000000..f5fb010
>--- /dev/null
>+++ b/src/compiler/glsl/int64.glsl
>@@ -0,0 +1,19 @@
>+/* Compile with:
>+ *
>+ * glsl_compiler --version 140 --dump-builder int64.glsl > builtin_int64.h
>+ *
>+ * Using version 1.40+ prevents built-in variables from being included.
>+ */

I'm not in love with checking in generated code, but I detest the
build-time bootstrapping... so I guess I'm okay with this.

If it were just this and sign64, I'd definitely advocate for just coding
them directly.

>+#version 140
>+#extension GL_MESA_shader_integer_functions: require
>+
>+uvec2
>+umul64(uvec2 a, uvec2 b)
>+{
>+   uvec2 result;
>+
>+   umulExtended(a.x, b.x, result.y, result.x);
>+   result.y += a.x * b.y + a.y * b.x;
>+
>+   return result;
>+}
>-- 
>2.7.4
>
>_______________________________________________
>mesa-dev mailing list
>mesa-dev at lists.freedesktop.org
>https://lists.freedesktop.org/mailman/listinfo/mesa-dev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: Digital signature
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20161130/e2a2fcc6/attachment-0001.sig>


More information about the mesa-dev mailing list