'clc.c',
'clc_helpers.cpp',
'nir_load_libclc.c',
- 'nir_lower_libclc.c',
)
_libmesaclc_c_args = []
const nir_shader_compiler_options *nir_options,
bool optimize);
-bool nir_lower_libclc(nir_shader *shader, const nir_shader *clc_shader);
-
#ifdef __cplusplus
}
#endif
+++ /dev/null
-/*
- * Copyright © 2019 Red Hat
- *
- * 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.
- *
- */
-
-/* Pass to find libclc functions from a clc library shader and inline
- * them into a user shader.
- * This pass should only be called once, but it also has to iterate
- * itself to make sure all instances are lowered, before validation.
- */
-#include "nir.h"
-#include "nir_clc_helpers.h"
-#include "nir_builder.h"
-#include "nir_spirv.h"
-
-static bool
-lower_clc_call_instr(nir_instr *instr, nir_builder *b,
- const nir_shader *clc_shader,
- struct hash_table *copy_vars)
-{
- nir_call_instr *call = nir_instr_as_call(instr);
- nir_function *func = NULL;
-
- if (!call->callee->name)
- return false;
-
- nir_foreach_function(function, clc_shader) {
- if (strcmp(function->name, call->callee->name) == 0) {
- func = function;
- break;
- }
- }
- if (!func || !func->impl) {
- return false;
- }
-
- nir_def **params = rzalloc_array(b->shader, nir_def*, call->num_params);
-
- for (unsigned i = 0; i < call->num_params; i++) {
- params[i] = nir_ssa_for_src(b, call->params[i],
- call->callee->params[i].num_components);
- }
-
- b->cursor = nir_instr_remove(&call->instr);
- nir_inline_function_impl(b, func->impl, params, copy_vars);
-
- ralloc_free(params);
-
- return true;
-}
-
-static bool
-nir_lower_libclc_impl(nir_function_impl *impl,
- const nir_shader *clc_shader,
- struct hash_table *copy_vars)
-{
- nir_builder b = nir_builder_create(impl);
-
- bool progress = false;
- nir_foreach_block_safe(block, impl) {
- nir_foreach_instr_safe(instr, block) {
- if (instr->type == nir_instr_type_call)
- progress |= lower_clc_call_instr(instr, &b, clc_shader, copy_vars);
- }
- }
-
- if (progress) {
- nir_index_ssa_defs(impl);
- nir_metadata_preserve(impl, nir_metadata_none);
- } else {
- nir_metadata_preserve(impl, nir_metadata_all);
- }
-
- return progress;
-}
-
-bool
-nir_lower_libclc(nir_shader *shader,
- const nir_shader *clc_shader)
-{
- void *ra_ctx = ralloc_context(NULL);
- struct hash_table *copy_vars = _mesa_pointer_hash_table_create(ra_ctx);
- bool progress = false, overall_progress = false;
-
- /* do progress passes inside the pass */
- do {
- progress = false;
- nir_foreach_function_impl(impl, shader) {
- progress |= nir_lower_libclc_impl(impl, clc_shader, copy_vars);
- }
- overall_progress |= progress;
- } while (progress);
-
- ralloc_free(ra_ctx);
-
- return overall_progress;
-}
nir_def **params,
struct hash_table *shader_var_remap);
bool nir_inline_functions(nir_shader *shader);
+bool nir_link_shader_functions(nir_shader *shader,
+ const nir_shader *link_shader);
void nir_find_inlinable_uniforms(nir_shader *shader);
void nir_inline_uniforms(nir_shader *shader, unsigned num_uniforms,
return progress;
}
+
+static bool
+lower_function_link_call_instr(nir_instr *instr, nir_builder *b,
+ const nir_shader *link_shader,
+ struct hash_table *copy_vars)
+{
+ nir_call_instr *call = nir_instr_as_call(instr);
+ nir_function *func = NULL;
+
+ if (!call->callee->name)
+ return false;
+
+ nir_foreach_function(function, link_shader) {
+ if (strcmp(function->name, call->callee->name) == 0) {
+ func = function;
+ break;
+ }
+ }
+ if (!func || !func->impl) {
+ return false;
+ }
+
+ nir_def **params = rzalloc_array(b->shader, nir_def*, call->num_params);
+
+ for (unsigned i = 0; i < call->num_params; i++) {
+ params[i] = nir_ssa_for_src(b, call->params[i],
+ call->callee->params[i].num_components);
+ }
+
+ b->cursor = nir_instr_remove(&call->instr);
+ nir_inline_function_impl(b, func->impl, params, copy_vars);
+
+ ralloc_free(params);
+
+ return true;
+}
+
+static bool
+lower_function_link_impl(nir_function_impl *impl,
+ const nir_shader *link_shader,
+ struct hash_table *copy_vars)
+{
+ nir_builder b = nir_builder_create(impl);
+
+ bool progress = false;
+ nir_foreach_block_safe(block, impl) {
+ nir_foreach_instr_safe(instr, block) {
+ if (instr->type == nir_instr_type_call)
+ progress |= lower_function_link_call_instr(instr, &b, link_shader, copy_vars);
+ }
+ }
+
+ if (progress) {
+ nir_index_ssa_defs(impl);
+ nir_metadata_preserve(impl, nir_metadata_none);
+ } else {
+ nir_metadata_preserve(impl, nir_metadata_all);
+ }
+
+ return progress;
+}
+
+bool
+nir_link_shader_functions(nir_shader *shader,
+ const nir_shader *link_shader)
+{
+ void *ra_ctx = ralloc_context(NULL);
+ struct hash_table *copy_vars = _mesa_pointer_hash_table_create(ra_ctx);
+ bool progress = false, overall_progress = false;
+
+ /* do progress passes inside the pass */
+ do {
+ progress = false;
+ nir_foreach_function_impl(impl, shader) {
+ progress |= lower_function_link_impl(impl, link_shader, copy_vars);
+ }
+ overall_progress |= progress;
+ } while (progress);
+
+ ralloc_free(ra_ctx);
+
+ return overall_progress;
+}
// according to the comment on nir_inline_functions
NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp);
NIR_PASS_V(nir, nir_lower_returns);
- NIR_PASS_V(nir, nir_lower_libclc, spirv_options.clc_shader);
+ NIR_PASS_V(nir, nir_link_shader_functions, spirv_options.clc_shader);
NIR_PASS_V(nir, nir_inline_functions);
NIR_PASS_V(nir, nir_copy_prop);
nir_variable_mode::nir_var_function_temp,
);
nir_pass!(self, nir_lower_returns);
- nir_pass!(self, nir_lower_libclc, libclc.nir.as_ptr());
+ nir_pass!(self, nir_link_shader_functions, libclc.nir.as_ptr());
nir_pass!(self, nir_inline_functions);
}
}
NIR_PASS_V(nir, implement_intel_builtins);
- NIR_PASS_V(nir, nir_lower_libclc, spirv_options.clc_shader);
+ NIR_PASS_V(nir, nir_link_shader_functions, spirv_options.clc_shader);
/* We have to lower away local constant initializers right before we
* inline functions. That way they get properly initialized at the top
// according to the comment on nir_inline_functions
NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp);
NIR_PASS_V(nir, nir_lower_returns);
- NIR_PASS_V(nir, nir_lower_libclc, clc_libclc_get_clc_shader(lib));
+ NIR_PASS_V(nir, nir_link_shader_functions, clc_libclc_get_clc_shader(lib));
NIR_PASS_V(nir, nir_inline_functions);
// Pick off the single entrypoint that we want.