First off, I should point out that the AMD NIR -> LLVM translator is, as far as I know, the only NIR back-end that consumes variables at all. Most back-ends assume that all variable access is completely lowered away before the back-end ever sees it. How this is done depends on the variable mode.
For nir_var_shader_temp, these are typically converted to nir_var_function_temp by nir_lower_global_vars_to_local after function inlining has completed. For nir_var_function_temp, it's some combination of nir_lower_vars_to_ssa, nir_lower_indirect_derefs, and nir_lower_locals_to_regs. If the back-end wants to be able to handle indirect access (such as with a non-constant array index) directly, it will typically use nir_lower_locals_to_regs. If the back-end doesn't want to handle indirects, it will use nir_lower_indirect_derefs to get rid of any indirects at which point nir_lower_vars_to_ssa will get rid of all access to nir_var_function_temp variables assuming complete deref chains. (Incomplete deref chains can happen with OpenCL kernel so they require a different approach.) Next, we have driver-internal I/O for things like vertex attributes, varyings, and uniforms, i.e. nir_var_shader_in, nir_var_shader_out, and nir_var_uniform. This is typically handled by nir_lower_io. This call takes a type_size callback function which it ses to lay out the I/O data in some sort of index space. For nir_var_uniform, this is often bytes (but doesn't have to be). For nir_var_shader_in and nir_var_shader_out, it's typically in units of vec4 locations. The result of this lowering is a bunch of load/store_input/output intrinsics. For FS inputs, nir_lower_io can optionally produce interpolation intrinsics instead. The final major category is external I/O. For this, we use nir_lower_explicit_io and friends. One difference between nir_lower_io and nir_lower_explicit_io is that nir_lower_explicit_io expects types to have explicit layout information (which is always in units of bytes) rather than taking it from a callback. Another difference is that nir_lower_explicit_io is capable of handling incomplete deref chains where pointer casts, pointer arithmetic, and other weirdness may exist while nir_lower_io assumes full deref chains all the time. For Vulkan, we need explicit type layout information because that's what we get from SPIR-V and we need partial deref chains because of extensions like VK_KHR_variable_pointers. For OpenGL, we have neither of those things but we use nir_lower_explicit_io anyway because we want the consistency and because the std140/430 layouts are a little too complex to describe with the callback used by nir_lower_io. Lastly, we have nir_var_system_value which is lowered by nir_lower_system_values and nir_lower_cs_system_values. I hope that helps. I should really turn this into a blog post or, better yet, real documentation.... --Jason On Sun, Oct 11, 2020 at 6:27 AM vivek pandya <vivekvpan...@gmail.com> wrote: > > I see that > visit_load_var() in ~/mesa/src/amd/llvm/ac_nir_to_llvm.c > > assumes that nir_variable used in this intrinsic can have few specific mods > only. > > For example variable can not have nir_var_mem_shared , if such mod > encountered it will execute unreachable() code. > > Is there any nir pass that needs to be run before nir_to_llvm translation? > > Sincerely, > Vivek > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev