X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Ffrontends%2Fclover%2Fnir%2Finvocation.cpp;h=8ea6d3cf4d08f9b6bbe9cab4d009115e42e17d29;hb=526f3566332e6fdf3bc413471a1a6e5ad091f0c5;hp=cae6ff235bab229c106668314288b92218640e2f;hpb=384c4df23dafa516fbe76e2844b259087400543f;p=mesa.git diff --git a/src/gallium/frontends/clover/nir/invocation.cpp b/src/gallium/frontends/clover/nir/invocation.cpp index cae6ff235ba..8ea6d3cf4d0 100644 --- a/src/gallium/frontends/clover/nir/invocation.cpp +++ b/src/gallium/frontends/clover/nir/invocation.cpp @@ -26,11 +26,13 @@ #include "core/device.hpp" #include "core/error.hpp" +#include "core/module.hpp" #include "pipe/p_state.h" #include "util/algorithm.hpp" #include "util/functional.hpp" #include +#include #include #include #include @@ -58,18 +60,102 @@ dev_get_nir_compiler_options(const device &dev) return static_cast(co); } +static void debug_function(void *private_data, + enum nir_spirv_debug_level level, size_t spirv_offset, + const char *message) +{ + assert(private_data); + auto r_log = reinterpret_cast(private_data); + *r_log += message; +} + +struct clover_lower_nir_state { + std::vector &args; + uint32_t global_dims; + nir_variable *offset_vars[3]; +}; + +static bool +clover_lower_nir_filter(const nir_instr *instr, const void *) +{ + return instr->type == nir_instr_type_intrinsic; +} + +static nir_ssa_def * +clover_lower_nir_instr(nir_builder *b, nir_instr *instr, void *_state) +{ + clover_lower_nir_state *state = reinterpret_cast(_state); + nir_intrinsic_instr *intrinsic = nir_instr_as_intrinsic(instr); + + switch (intrinsic->intrinsic) { + case nir_intrinsic_load_base_global_invocation_id: { + nir_ssa_def *loads[3]; + + /* create variables if we didn't do so alrady */ + if (!state->offset_vars[0]) { + /* TODO: fix for 64 bit */ + /* Even though we only place one scalar argument, clover will bind up to + * three 32 bit values + */ + state->args.emplace_back(module::argument::scalar, 4, 4, 4, + module::argument::zero_ext, + module::argument::grid_offset); + + const glsl_type *type = glsl_uint_type(); + for (uint32_t i = 0; i < 3; i++) { + state->offset_vars[i] = + nir_variable_create(b->shader, nir_var_uniform, type, + "global_invocation_id_offsets"); + state->offset_vars[i]->data.location = b->shader->num_uniforms++; + } + } + + for (int i = 0; i < 3; i++) { + nir_variable *var = state->offset_vars[i]; + loads[i] = var ? nir_load_var(b, var) : nir_imm_int(b, 0); + } + + return nir_u2u(b, nir_vec(b, loads, state->global_dims), + nir_dest_bit_size(intrinsic->dest)); + } + default: + return NULL; + } +} + +static bool +clover_lower_nir(nir_shader *nir, std::vector &args, uint32_t dims) +{ + clover_lower_nir_state state = { args, dims }; + return nir_shader_lower_instructions(nir, + clover_lower_nir_filter, clover_lower_nir_instr, &state); +} + module clover::nir::spirv_to_nir(const module &mod, const device &dev, std::string &r_log) { struct spirv_to_nir_options spirv_options = {}; spirv_options.environment = NIR_SPIRV_OPENCL; + if (dev.address_bits() == 32u) { + spirv_options.shared_addr_format = nir_address_format_32bit_offset; + spirv_options.global_addr_format = nir_address_format_32bit_global; + spirv_options.temp_addr_format = nir_address_format_32bit_offset; + spirv_options.constant_addr_format = nir_address_format_32bit_global; + } else { + spirv_options.shared_addr_format = nir_address_format_32bit_offset_as_64bit; + spirv_options.global_addr_format = nir_address_format_64bit_global; + spirv_options.temp_addr_format = nir_address_format_32bit_offset_as_64bit; + spirv_options.constant_addr_format = nir_address_format_64bit_global; + } spirv_options.caps.address = true; spirv_options.caps.float64 = true; spirv_options.caps.int8 = true; spirv_options.caps.int16 = true; spirv_options.caps.int64 = true; spirv_options.caps.kernel = true; - spirv_options.constant_as_global = true; + spirv_options.caps.int64_atomics = dev.has_int64_atomics(); + spirv_options.debug.func = &debug_function; + spirv_options.debug.private_data = &r_log; module m; // We only insert one section. @@ -99,14 +185,6 @@ module clover::nir::spirv_to_nir(const module &mod, const device &dev, nir->info.cs.local_size_variable = true; nir_validate_shader(nir, "clover"); - // Calculate input offsets. - unsigned offset = 0; - nir_foreach_shader_in_variable_safe(var, nir) { - offset = align(offset, glsl_get_cl_alignment(var->type)); - var->data.driver_location = offset; - offset += glsl_get_cl_size(var->type); - } - // Inline all functions first. // according to the comment on nir_inline_functions NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp); @@ -124,8 +202,7 @@ module clover::nir::spirv_to_nir(const module &mod, const device &dev, nir_validate_shader(nir, "clover after function inlining"); - NIR_PASS_V(nir, nir_lower_variable_initializers, - static_cast(~nir_var_function_temp)); + NIR_PASS_V(nir, nir_lower_variable_initializers, ~nir_var_function_temp); // copy propagate to prepare for lower_explicit_io NIR_PASS_V(nir, nir_split_var_copies); @@ -134,18 +211,45 @@ module clover::nir::spirv_to_nir(const module &mod, const device &dev, NIR_PASS_V(nir, nir_lower_vars_to_ssa); NIR_PASS_V(nir, nir_opt_dce); - /* use offsets for shader_in and shared memory */ - nir_variable_mode modes = (nir_variable_mode)( - nir_var_shader_in | - nir_var_mem_shared); - NIR_PASS_V(nir, nir_lower_explicit_io, modes, nir_address_format_32bit_offset); + NIR_PASS_V(nir, nir_lower_system_values); + nir_lower_compute_system_values_options sysval_options = { 0 }; + sysval_options.has_base_global_invocation_id = true; + NIR_PASS_V(nir, nir_lower_compute_system_values, &sysval_options); - /* use global format for global memory */ - nir_address_format format = nir->info.cs.ptr_size == 64 ? - nir_address_format_64bit_global : nir_address_format_32bit_global; - NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_global, format); + auto args = sym.args; + NIR_PASS_V(nir, clover_lower_nir, args, dev.max_block_size().size()); + + // Calculate input offsets. + unsigned offset = 0; + nir_foreach_uniform_variable(var, nir) { + offset = align(offset, glsl_get_cl_alignment(var->type)); + var->data.driver_location = offset; + offset += glsl_get_cl_size(var->type); + } + + NIR_PASS_V(nir, nir_lower_vars_to_explicit_types, + nir_var_mem_shared | nir_var_function_temp, + glsl_get_cl_type_size_align); + + /* use offsets for kernel inputs (uniform) */ + NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_uniform, + nir->info.cs.ptr_size == 64 ? + nir_address_format_32bit_offset_as_64bit : + nir_address_format_32bit_offset); + + NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_constant, + spirv_options.constant_addr_format); + NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_shared, + spirv_options.shared_addr_format); + + NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_function_temp, + spirv_options.temp_addr_format); + + NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_global, + spirv_options.global_addr_format); + + NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_all, NULL); - NIR_PASS_V(nir, nir_lower_system_values); if (compiler_options->lower_int64_options) NIR_PASS_V(nir, nir_lower_int64); @@ -161,7 +265,7 @@ module clover::nir::spirv_to_nir(const module &mod, const device &dev, reinterpret_cast(&header) + sizeof(header)); text.data.insert(text.data.end(), blob.data, blob.data + blob.size); - m.syms.emplace_back(sym.name, section_id, 0, sym.args); + m.syms.emplace_back(sym.name, section_id, 0, args); m.secs.push_back(text); section_id++; }