Lavapipe support on Fuchsia.

This primarily involves adding BUILD.gn files corresponding to the
existing meson.build files.  However, some other changes were needed,
most notably providing LLVM with a custom memory mapper which is able
to mark allocated pages as executable (Fuchsia does this differently
than other platforms).

Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/mesa/+/976872
Reviewed-by: John Rosasco <rosasco@google.com>

[lavapipe] Fix build error, missing input

Change-Id: I8870024328c59072c945e79d672dd17a2e4b3797
Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/mesa/+/1005629
Reviewed-by: John Bauman <jbauman@google.com>
Commit-Queue: John Rosasco <rosasco@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 7300140..d0e3bde 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -34,3 +34,31 @@
     "tests",
   ]
 }
+
+config("build_config") {
+  defines = [
+    "LLVM_AVAILABLE",
+
+    # In meson.build, this refers to the LLVM version required to support the selected features
+    # (e.g. in Lavapipe).  It is *not* the version of the LLVM we are using, although that version
+    # must be >= the value listed here.
+    "MESA_LLVM_VERSION_STRING=\">= 17.0.0\"",
+    "LLVM_IS_SHARED=0",
+    "DRAW_LLVM_AVAILABLE=1",
+
+    "GALLIUM_LLVMPIPE",
+  ]
+
+  if (is_fuchsia) {
+    defines += [ "VK_USE_PLATFORM_FUCHSIA=1" ]
+  }
+}
+
+# TODO(b/321122796): temporary, this should be replaced by `//src/lib/llvm:LLVMHeader_config` at
+# some point, once that one uses platform-specific headers, not just the ${host_platform} ones.
+# This also works around a versioning problem: the sandbox version of LLVM used by Mesa is newer
+# than the prebuilt headers.
+config("LLVMHeader_config") {
+  cflags = [ "-isystem" + rebase_path("//prebuilt/third_party/llvm/${current_platform}/include",
+                                      root_build_dir) ]
+}
\ No newline at end of file
diff --git a/src/compiler/nir/BUILD.gn b/src/compiler/nir/BUILD.gn
index 3ce1f5d..fa81bed 100644
--- a/src/compiler/nir/BUILD.gn
+++ b/src/compiler/nir/BUILD.gn
@@ -39,6 +39,7 @@
     ":nir_compiler_workaround",
     "$mesa_build_root/include:c_compat",
     "$mesa_build_root/src/compiler/glsl:ir_expression_operation",
+    "$mesa_build_root/src/compiler/spirv",
     "$mesa_build_root/src/util",
   ]
 
@@ -54,34 +55,63 @@
     "nir_builder.c",
     "nir_builder.h",
     "nir_builtin_builder.c",
+    "nir_builtin_builder.h",
     "nir_clone.c",
     "nir_constant_expressions.h",
     "nir_control_flow.c",
     "nir_control_flow.h",
     "nir_control_flow_private.h",
+    "nir_conversion_builder.h",
     "nir_convert_ycbcr.c",
     "nir_deref.c",
+    "nir_deref.h",
     "nir_divergence_analysis.c",
     "nir_dominance.c",
+    "nir_format_convert.h",
     "nir_from_ssa.c",
     "nir_gather_info.c",
+    "nir_gather_ssa_types.c",
     "nir_gather_xfb_info.c",
+    "nir_group_loads.c",
     "nir_gs_count_vertices.c",
     "nir_inline_functions.c",
+    "nir_inline_uniforms.c",
     "nir_instr_set.c",
     "nir_instr_set.h",
     "nir_linking_helpers.c",
     "nir_liveness.c",
     "nir_loop_analyze.c",
+    "nir_loop_analyze.h",
+    "nir_lower_alpha_test.c",
+    "nir_lower_alu.c",
     "nir_lower_alu_width.c",
+    "nir_lower_amul.c",
     "nir_lower_array_deref_of_vec.c",
+    "nir_lower_atomics_to_ssbo.c",
     "nir_lower_bit_size.c",
+    "nir_lower_bitmap.c",
+    "nir_lower_blend.c",
+    "nir_lower_bool_to_bitsize.c",
+    "nir_lower_bool_to_float.c",
     "nir_lower_bool_to_int32.c",
+    "nir_lower_cl_images.c",
+    "nir_lower_clamp_color_outputs.c",
     "nir_lower_clip.c",
     "nir_lower_clip_cull_distance_arrays.c",
+    "nir_lower_clip_disable.c",
+    "nir_lower_clip_halfz.c",
+    "nir_lower_const_arrays_to_uniforms.c",
     "nir_lower_convert_alu_types.c",
+    "nir_lower_discard_if.c",
+    "nir_lower_discard_or_demote.c",
     "nir_lower_double_ops.c",
+    "nir_lower_drawpixels.c",
+    "nir_lower_fb_read.c",
+    "nir_lower_flatshade.c",
     "nir_lower_flrp.c",
+    "nir_lower_fp16_conv.c",
+    "nir_lower_fragcolor.c",
+    "nir_lower_fragcoord_wtrans.c",
     "nir_lower_frexp.c",
     "nir_lower_global_vars_to_local.c",
     "nir_lower_goto_ifs.c",
@@ -91,36 +121,62 @@
     "nir_lower_indirect_derefs.c",
     "nir_lower_input_attachments.c",
     "nir_lower_int64.c",
+    "nir_lower_int_to_float.c",
     "nir_lower_interpolation.c",
     "nir_lower_io.c",
     "nir_lower_io_arrays_to_elements.c",
     "nir_lower_io_to_scalar.c",
     "nir_lower_io_to_temporaries.c",
     "nir_lower_io_to_vector.c",
+    "nir_lower_is_helper_invocation.c",
     "nir_lower_load_const_to_scalar.c",
     "nir_lower_locals_to_regs.c",
+    "nir_lower_mediump.c",
+    "nir_lower_memcpy.c",
+    "nir_lower_memory_model.c",
     "nir_lower_multiview.c",
     "nir_lower_non_uniform_access.c",
     "nir_lower_packing.c",
+    "nir_lower_passthrough_edgeflags.c",
     "nir_lower_patch_vertices.c",
     "nir_lower_phis_to_scalar.c",
+    "nir_lower_pntc_ytransform.c",
+    "nir_lower_point_size.c",
+    "nir_lower_point_size_mov.c",
+    "nir_lower_point_smooth.c",
+    "nir_lower_poly_line_smooth.c",
+    "nir_lower_printf.c",
+    "nir_lower_readonly_images_to_tex.c",
     "nir_lower_regs_to_ssa.c",
     "nir_lower_returns.c",
+    "nir_lower_samplers.c",
     "nir_lower_scratch.c",
     "nir_lower_shader_calls.c",
     "nir_lower_single_sampled.c",
+    "nir_lower_ssbo.c",
     "nir_lower_subgroups.c",
     "nir_lower_system_values.c",
     "nir_lower_sysvals_to_varyings.c",
     "nir_lower_task_shader.c",
     "nir_lower_tex.c",
+    "nir_lower_tex_shadow.c",
+    "nir_lower_texcoord_replace.c",
     "nir_lower_to_source_mods.c",
     "nir_lower_two_sided_color.c",
+    "nir_lower_ubo_vec4.c",
+    "nir_lower_undef_to_zero.c",
+    "nir_lower_uniforms_to_ubo.c",
     "nir_lower_var_copies.c",
     "nir_lower_variable_initializers.c",
     "nir_lower_vars_to_ssa.c",
+    "nir_lower_vec3_to_vec4.c",
     "nir_lower_vec_to_movs.c",
+    "nir_lower_viewport_transform.c",
     "nir_lower_wpos_center.c",
+
+    # see ":nir_compiler_workaround"
+    # "nir_lower_wpos_ytransform.c",
+    "nir_lower_wrmasks.c",
     "nir_metadata.c",
     "nir_move_vec_src_uses_to_dest.c",
     "nir_normalize_cubemap_coords.c",
@@ -137,19 +193,24 @@
     "nir_opt_dead_cf.c",
     "nir_opt_dead_write_vars.c",
     "nir_opt_find_array_copies.c",
+    "nir_opt_fragdepth.c",
     "nir_opt_gcm.c",
     "nir_opt_idiv_const.c",
     "nir_opt_if.c",
     "nir_opt_intrinsics.c",
-    "nir_opt_memcpy.c",
     "nir_opt_large_constants.c",
     "nir_opt_load_store_vectorize.c",
     "nir_opt_loop_unroll.c",
+    "nir_opt_memcpy.c",
     "nir_opt_move.c",
+    "nir_opt_move_discards_to_top.c",
     "nir_opt_non_uniform_access.c",
+    "nir_opt_offsets.c",
     "nir_opt_peephole_select.c",
-    "nir_opt_rematerialize_compares.c",
+    "nir_opt_phi_precision.c",
+    "nir_opt_preamble.c",
     "nir_opt_ray_queries.c",
+    "nir_opt_rematerialize_compares.c",
     "nir_opt_remove_phis.c",
     "nir_opt_shrink_stores.c",
     "nir_opt_shrink_vectors.c",
@@ -157,15 +218,25 @@
     "nir_opt_trivial_continues.c",
     "nir_opt_undef.c",
     "nir_opt_uniform_atomics.c",
+    "nir_opt_vectorize.c",
+    "nir_passthrough_tcs.c",
     "nir_phi_builder.c",
+    "nir_phi_builder.h",
     "nir_print.c",
     "nir_propagate_invariant.c",
     "nir_range_analysis.c",
+    "nir_range_analysis.h",
     "nir_remove_dead_variables.c",
     "nir_repair_ssa.c",
+    "nir_scale_fdiv.c",
+    "nir_schedule.c",
+    "nir_schedule.h",
     "nir_search.c",
     "nir_search.h",
+    "nir_search_helpers.h",
     "nir_serialize.c",
+    "nir_serialize.h",
+    "nir_split_64bit_vec3_and_vec4.c",
     "nir_split_per_member_structs.c",
     "nir_split_var_copies.c",
     "nir_split_vars.c",
@@ -173,8 +244,10 @@
     "nir_to_lcssa.c",
     "nir_validate.c",
     "nir_vla.h",
+    "nir_vulkan.h",
     "nir_worklist.c",
     "nir_worklist.h",
+    "nir_xfb_info.h",
   ]
 
   # Suppress warnings the nir code doesn't comply with.
@@ -282,7 +355,10 @@
 
   outputs = [ "$target_gen_dir/$output_name" ]
 
-  inputs = [ "$script", "nir_intrinsics.py" ] + third_party_mako_srcs
+  inputs = [
+             "$script",
+             "nir_intrinsics.py",
+           ] + third_party_mako_srcs
 
   args = [
     "--outdir",
diff --git a/src/compiler/spirv/BUILD.gn b/src/compiler/spirv/BUILD.gn
index 54e1468..4fd9767 100644
--- a/src/compiler/spirv/BUILD.gn
+++ b/src/compiler/spirv/BUILD.gn
@@ -23,7 +23,10 @@
 import("../../../mesa.gni")
 
 config("spirv_public_config") {
-  include_dirs = [ "." ]
+  include_dirs = [
+    ".",
+    "$target_gen_dir",
+  ]
 }
 
 mesa_source_set("spirv") {
@@ -34,15 +37,27 @@
     ":vtn_gather_types",
     ":vtn_generator_ids_h",
     "$mesa_build_root/include:c_compat",
-    "$mesa_build_root/src/compiler/nir",
+    "$mesa_build_root/src/compiler/nir:gen",
     "$mesa_build_root/src/util",
   ]
 
-  include_dirs = [ "..", "$target_gen_dir" ]
+  include_dirs = [
+    "..",
+    "$mesa_build_root/src/compiler/nir",
+  ]
 
   sources = [
     "$target_gen_dir/spirv_info.c",
     "$target_gen_dir/vtn_gather_types.c",
+    "GLSL.ext.AMD.h",
+    "GLSL.std.450.h",
+    "OpenCL.std.h",
+    "gl_spirv.c",
+    "nir_load_libclc.c",
+    "nir_lower_libclc.c",
+    "nir_spirv.h",
+    "spirv.h",
+    "spirv_info.h",
     "spirv_to_nir.c",
     "vtn_alu.c",
     "vtn_amd.c",
diff --git a/src/gallium/BUILD.gn b/src/gallium/BUILD.gn
new file mode 100644
index 0000000..9f445c9
--- /dev/null
+++ b/src/gallium/BUILD.gn
@@ -0,0 +1,29 @@
+# Copyright 2023 Google, LLC
+#
+# 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.
+
+import("../../mesa.gni")
+
+config("build_config") {
+  defines = [ "GALLIUM_STATIC_TARGETS=1" ]
+
+  # Suppress warnings.
+  configs = [ "//build/config:Wno-strict-prototypes" ]
+}
diff --git a/src/gallium/auxiliary/BUILD.gn b/src/gallium/auxiliary/BUILD.gn
new file mode 100644
index 0000000..6de1618
--- /dev/null
+++ b/src/gallium/auxiliary/BUILD.gn
@@ -0,0 +1,543 @@
+# Copyright 2023 Google, LLC
+#
+# 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.
+
+import("//third_party/mako/py_srcs.gni")
+import("../../../mesa.gni")
+
+mesa_source_set("gallivm") {
+  sources = [
+    "draw/draw_llvm.c",
+    "draw/draw_llvm.h",
+    "draw/draw_llvm_sample.c",
+    "draw/draw_pt_fetch_shade_pipeline_llvm.c",
+    "draw/draw_vs_llvm.c",
+    "gallivm/lp_bld.h",
+    "gallivm/lp_bld_arit.c",
+    "gallivm/lp_bld_arit.h",
+    "gallivm/lp_bld_arit_overflow.c",
+    "gallivm/lp_bld_arit_overflow.h",
+    "gallivm/lp_bld_assert.c",
+    "gallivm/lp_bld_assert.h",
+    "gallivm/lp_bld_bitarit.c",
+    "gallivm/lp_bld_bitarit.h",
+    "gallivm/lp_bld_const.c",
+    "gallivm/lp_bld_const.h",
+    "gallivm/lp_bld_conv.c",
+    "gallivm/lp_bld_conv.h",
+    "gallivm/lp_bld_coro.c",
+    "gallivm/lp_bld_coro.h",
+    "gallivm/lp_bld_debug.cpp",
+    "gallivm/lp_bld_debug.h",
+    "gallivm/lp_bld_flow.c",
+    "gallivm/lp_bld_flow.h",
+    "gallivm/lp_bld_format.c",
+    "gallivm/lp_bld_format.h",
+    "gallivm/lp_bld_format_aos.c",
+    "gallivm/lp_bld_format_aos_array.c",
+    "gallivm/lp_bld_format_float.c",
+    "gallivm/lp_bld_format_s3tc.c",
+    "gallivm/lp_bld_format_soa.c",
+    "gallivm/lp_bld_format_srgb.c",
+    "gallivm/lp_bld_format_yuv.c",
+    "gallivm/lp_bld_fuchsia_memory_mapper.cpp",
+    "gallivm/lp_bld_fuchsia_memory_mapper.hpp",
+    "gallivm/lp_bld_gather.c",
+    "gallivm/lp_bld_gather.h",
+    "gallivm/lp_bld_init.c",
+    "gallivm/lp_bld_init.h",
+    "gallivm/lp_bld_intr.c",
+    "gallivm/lp_bld_intr.h",
+    "gallivm/lp_bld_ir_common.c",
+    "gallivm/lp_bld_ir_common.h",
+    "gallivm/lp_bld_jit_types.c",
+    "gallivm/lp_bld_jit_types.h",
+    "gallivm/lp_bld_limits.h",
+    "gallivm/lp_bld_logic.c",
+    "gallivm/lp_bld_logic.h",
+    "gallivm/lp_bld_misc.cpp",
+    "gallivm/lp_bld_misc.h",
+    "gallivm/lp_bld_nir.c",
+    "gallivm/lp_bld_nir.h",
+    "gallivm/lp_bld_nir_aos.c",
+    "gallivm/lp_bld_nir_soa.c",
+    "gallivm/lp_bld_pack.c",
+    "gallivm/lp_bld_pack.h",
+    "gallivm/lp_bld_printf.c",
+    "gallivm/lp_bld_printf.h",
+    "gallivm/lp_bld_quad.c",
+    "gallivm/lp_bld_quad.h",
+    "gallivm/lp_bld_sample.c",
+    "gallivm/lp_bld_sample.h",
+    "gallivm/lp_bld_sample_aos.c",
+    "gallivm/lp_bld_sample_aos.h",
+    "gallivm/lp_bld_sample_soa.c",
+    "gallivm/lp_bld_struct.c",
+    "gallivm/lp_bld_struct.h",
+    "gallivm/lp_bld_swizzle.c",
+    "gallivm/lp_bld_swizzle.h",
+    "gallivm/lp_bld_tgsi.c",
+    "gallivm/lp_bld_tgsi.h",
+    "gallivm/lp_bld_tgsi_action.c",
+    "gallivm/lp_bld_tgsi_action.h",
+    "gallivm/lp_bld_tgsi_aos.c",
+    "gallivm/lp_bld_tgsi_info.c",
+    "gallivm/lp_bld_tgsi_soa.c",
+    "gallivm/lp_bld_type.c",
+    "gallivm/lp_bld_type.h",
+    "nir/nir_to_tgsi_info.c",
+    "nir/nir_to_tgsi_info.h",
+    "tessellator/p_tessellator.cpp",
+    "tessellator/p_tessellator.h",
+    "tessellator/tessellator.cpp",
+    "tessellator/tessellator.hpp",
+  ]
+
+  include_dirs = [
+    "$mesa_build_root/include/",
+    "$mesa_build_root/src/compiler/nir",
+    "$mesa_build_root/src/gallium/auxiliary/",
+    "$mesa_build_root/src/gallium/include/",
+    "$mesa_build_root/src/",
+  ]
+
+  deps = [
+    ":gen",
+    "$mesa_build_root/src/compiler/nir",
+    # TODO(b/321122796):
+    # These are for marking JIT memory as executable in lp_bld_fuchsia_memory_mapper.cpp.
+    # Perhaps this functionality should be moved into a separate target?
+    "//sdk/fidl/fuchsia.vulkan.loader:fuchsia.vulkan.loader_cpp",
+    "//sdk/lib/component/incoming/cpp",
+  ]
+
+  # Suppress warnings.
+  configs = [
+    "$mesa_build_root:build_config",
+    "//build/config:Wno-unused-but-set-variable",
+    "//build/config:Wno-strict-prototypes",
+    "//third_party/mesa:LLVMHeader_config",
+  ]
+}
+
+mesa_source_set("auxiliary") {
+  deps = [
+    ":gallivm",
+    ":gen",
+    "$mesa_build_root/src/compiler/nir",
+  ]
+
+  sources = [
+    "cso_cache/cso_cache.c",
+    "cso_cache/cso_cache.h",
+    "cso_cache/cso_context.c",
+    "cso_cache/cso_context.h",
+    "cso_cache/cso_hash.c",
+    "cso_cache/cso_hash.h",
+    "draw/draw_cliptest_tmp.h",
+    "draw/draw_context.c",
+    "draw/draw_context.h",
+    "draw/draw_decompose_tmp.h",
+    "draw/draw_fs.c",
+    "draw/draw_fs.h",
+    "draw/draw_gs.c",
+    "draw/draw_gs.h",
+    "draw/draw_gs_tmp.h",
+    "draw/draw_pipe.c",
+    "draw/draw_pipe.h",
+    "draw/draw_pipe_aaline.c",
+    "draw/draw_pipe_aapoint.c",
+    "draw/draw_pipe_clip.c",
+    "draw/draw_pipe_cull.c",
+    "draw/draw_pipe_flatshade.c",
+    "draw/draw_pipe_offset.c",
+    "draw/draw_pipe_pstipple.c",
+    "draw/draw_pipe_stipple.c",
+    "draw/draw_pipe_twoside.c",
+    "draw/draw_pipe_unfilled.c",
+    "draw/draw_pipe_user_cull.c",
+    "draw/draw_pipe_util.c",
+    "draw/draw_pipe_validate.c",
+    "draw/draw_pipe_vbuf.c",
+    "draw/draw_pipe_wide_line.c",
+    "draw/draw_pipe_wide_point.c",
+    "draw/draw_prim_assembler.c",
+    "draw/draw_prim_assembler.h",
+    "draw/draw_prim_assembler_tmp.h",
+    "draw/draw_private.h",
+    "draw/draw_pt.c",
+    "draw/draw_pt.h",
+    "draw/draw_pt_decompose.h",
+    "draw/draw_pt_emit.c",
+    "draw/draw_pt_fetch.c",
+    "draw/draw_pt_fetch_shade_emit.c",
+    "draw/draw_pt_fetch_shade_pipeline.c",
+    "draw/draw_pt_post_vs.c",
+    "draw/draw_pt_so_emit.c",
+    "draw/draw_pt_util.c",
+    "draw/draw_pt_vsplit.c",
+    "draw/draw_pt_vsplit_tmp.h",
+    "draw/draw_so_emit_tmp.h",
+    "draw/draw_split_tmp.h",
+    "draw/draw_tess.c",
+    "draw/draw_tess.h",
+    "draw/draw_vbuf.h",
+    "draw/draw_vertex.c",
+    "draw/draw_vertex.h",
+    "draw/draw_vs.c",
+    "draw/draw_vs.h",
+    "draw/draw_vs_exec.c",
+    "draw/draw_vs_variant.c",
+    "driver_ddebug/dd_context.c",
+    "driver_ddebug/dd_draw.c",
+    "driver_ddebug/dd_pipe.h",
+    "driver_ddebug/dd_public.h",
+    "driver_ddebug/dd_screen.c",
+    "driver_ddebug/dd_util.h",
+    "driver_noop/noop_pipe.c",
+    "driver_noop/noop_public.h",
+    "driver_noop/noop_state.c",
+    "driver_trace/tr_context.c",
+    "driver_trace/tr_context.h",
+    "driver_trace/tr_dump.c",
+    "driver_trace/tr_dump.h",
+    "driver_trace/tr_dump_defines.h",
+    "driver_trace/tr_dump_state.c",
+    "driver_trace/tr_dump_state.h",
+    "driver_trace/tr_public.h",
+    "driver_trace/tr_screen.c",
+    "driver_trace/tr_screen.h",
+    "driver_trace/tr_texture.c",
+    "driver_trace/tr_texture.h",
+    "hud/font.c",
+    "hud/font.h",
+    "hud/hud_context.c",
+    "hud/hud_context.h",
+    "hud/hud_cpu.c",
+    "hud/hud_cpufreq.c",
+    "hud/hud_diskstat.c",
+    "hud/hud_driver_query.c",
+    "hud/hud_fps.c",
+    "hud/hud_nic.c",
+    "hud/hud_private.h",
+    "hud/hud_sensors_temp.c",
+    "indices/u_indices.h",
+    "indices/u_indices_priv.h",
+    "indices/u_primconvert.c",
+    "indices/u_primconvert.h",
+    "nir/nir_draw_helpers.c",
+    "nir/nir_draw_helpers.h",
+    "nir/nir_helpers.c",
+    "nir/nir_helpers.h",
+    "nir/nir_to_tgsi.c",
+    "nir/nir_to_tgsi.h",
+    "nir/tgsi_to_nir.c",
+    "nir/tgsi_to_nir.h",
+    "os/os_mman.h",
+    "os/os_process.c",
+    "os/os_process.h",
+    "os/os_thread.h",
+    "pipebuffer/pb_buffer.h",
+    "pipebuffer/pb_buffer_fenced.c",
+    "pipebuffer/pb_buffer_fenced.h",
+    "pipebuffer/pb_bufmgr.h",
+    "pipebuffer/pb_bufmgr_cache.c",
+    "pipebuffer/pb_bufmgr_debug.c",
+    "pipebuffer/pb_bufmgr_mm.c",
+    "pipebuffer/pb_bufmgr_slab.c",
+    "pipebuffer/pb_cache.c",
+    "pipebuffer/pb_cache.h",
+    "pipebuffer/pb_slab.c",
+    "pipebuffer/pb_slab.h",
+    "pipebuffer/pb_validate.c",
+    "pipebuffer/pb_validate.h",
+    "postprocess/filters.h",
+    "postprocess/postprocess.h",
+    "postprocess/pp_celshade.c",
+    "postprocess/pp_celshade.h",
+    "postprocess/pp_colors.c",
+    "postprocess/pp_colors.h",
+    "postprocess/pp_filters.h",
+    "postprocess/pp_init.c",
+    "postprocess/pp_mlaa.c",
+    "postprocess/pp_mlaa.h",
+    "postprocess/pp_mlaa_areamap.h",
+    "postprocess/pp_private.h",
+    "postprocess/pp_program.c",
+    "postprocess/pp_run.c",
+    "rtasm/rtasm_execmem.c",
+    "rtasm/rtasm_execmem.h",
+    "rtasm/rtasm_x86sse.c",
+    "rtasm/rtasm_x86sse.h",
+    "tgsi/tgsi_aa_point.c",
+    "tgsi/tgsi_aa_point.h",
+    "tgsi/tgsi_build.c",
+    "tgsi/tgsi_build.h",
+    "tgsi/tgsi_dump.c",
+    "tgsi/tgsi_dump.h",
+    "tgsi/tgsi_dynamic_indexing.c",
+    "tgsi/tgsi_exec.c",
+    "tgsi/tgsi_exec.h",
+    "tgsi/tgsi_from_mesa.c",
+    "tgsi/tgsi_from_mesa.h",
+    "tgsi/tgsi_info.c",
+    "tgsi/tgsi_info.h",
+    "tgsi/tgsi_info_opcodes.h",
+    "tgsi/tgsi_iterate.c",
+    "tgsi/tgsi_iterate.h",
+    "tgsi/tgsi_lowering.c",
+    "tgsi/tgsi_lowering.h",
+    "tgsi/tgsi_opcode_tmp.h",
+    "tgsi/tgsi_parse.c",
+    "tgsi/tgsi_parse.h",
+    "tgsi/tgsi_point_sprite.c",
+    "tgsi/tgsi_point_sprite.h",
+    "tgsi/tgsi_sanity.c",
+    "tgsi/tgsi_sanity.h",
+    "tgsi/tgsi_scan.c",
+    "tgsi/tgsi_scan.h",
+    "tgsi/tgsi_strings.c",
+    "tgsi/tgsi_strings.h",
+    "tgsi/tgsi_text.c",
+    "tgsi/tgsi_text.h",
+    "tgsi/tgsi_transform.c",
+    "tgsi/tgsi_transform.h",
+    "tgsi/tgsi_two_side.c",
+    "tgsi/tgsi_two_side.h",
+    "tgsi/tgsi_ureg.c",
+    "tgsi/tgsi_ureg.h",
+    "tgsi/tgsi_util.c",
+    "tgsi/tgsi_util.h",
+    "tgsi/tgsi_vpos.c",
+    "translate/translate.c",
+    "translate/translate.h",
+    "translate/translate_cache.c",
+    "translate/translate_cache.h",
+    "translate/translate_generic.c",
+    "translate/translate_sse.c",
+    "util/dbghelp.h",
+    "util/u_async_debug.c",
+    "util/u_async_debug.h",
+    "util/u_bitcast.h",
+    "util/u_bitmask.c",
+    "util/u_bitmask.h",
+    "util/u_blend.h",
+    "util/u_blitter.c",
+    "util/u_blitter.h",
+    "util/u_box.h",
+    "util/u_cache.c",
+    "util/u_cache.h",
+    "util/u_compute.c",
+    "util/u_compute.h",
+    "util/u_debug_cb.h",
+    "util/u_debug_flush.c",
+    "util/u_debug_flush.h",
+    "util/u_debug_image.c",
+    "util/u_debug_image.h",
+    "util/u_dirty_flags.h",
+    "util/u_dirty_surfaces.h",
+    "util/u_draw.c",
+    "util/u_draw.h",
+    "util/u_draw_quad.c",
+    "util/u_draw_quad.h",
+    "util/u_driconf.c",
+    "util/u_driconf.h",
+    "util/u_dual_blend.h",
+    "util/u_dump.h",
+    "util/u_dump_defines.c",
+    "util/u_dump_state.c",
+    "util/u_framebuffer.c",
+    "util/u_framebuffer.h",
+    "util/u_gen_mipmap.c",
+    "util/u_gen_mipmap.h",
+    "util/u_handle_table.c",
+    "util/u_handle_table.h",
+    "util/u_helpers.c",
+    "util/u_helpers.h",
+    "util/u_index_modify.c",
+    "util/u_index_modify.h",
+    "util/u_inlines.h",
+    "util/u_linear.c",
+    "util/u_linear.h",
+    "util/u_live_shader_cache.c",
+    "util/u_live_shader_cache.h",
+    "util/u_log.c",
+    "util/u_log.h",
+    "util/u_pack_color.h",
+    "util/u_prim.c",
+    "util/u_prim.h",
+    "util/u_prim_restart.c",
+    "util/u_prim_restart.h",
+    "util/u_pstipple.c",
+    "util/u_pstipple.h",
+    "util/u_pwr8.h",
+    "util/u_range.h",
+    "util/u_rect.h",
+    "util/u_resource.c",
+    "util/u_resource.h",
+    "util/u_sampler.c",
+    "util/u_sampler.h",
+    "util/u_screen.c",
+    "util/u_screen.h",
+    "util/u_simple_shaders.c",
+    "util/u_simple_shaders.h",
+    "util/u_split_draw.c",
+    "util/u_split_draw.h",
+    "util/u_split_prim.h",
+    "util/u_sse.h",
+    "util/u_suballoc.c",
+    "util/u_suballoc.h",
+    "util/u_surface.c",
+    "util/u_surface.h",
+    "util/u_tests.c",
+    "util/u_tests.h",
+    "util/u_texture.c",
+    "util/u_texture.h",
+    "util/u_threaded_context.c",
+    "util/u_threaded_context.h",
+    "util/u_threaded_context_calls.h",
+    "util/u_tile.c",
+    "util/u_tile.h",
+    "util/u_trace_gallium.c",
+    "util/u_trace_gallium.h",
+    "util/u_transfer.c",
+    "util/u_transfer.h",
+    "util/u_transfer_helper.c",
+    "util/u_transfer_helper.h",
+    "util/u_upload_mgr.c",
+    "util/u_upload_mgr.h",
+    "util/u_vbuf.c",
+    "util/u_vbuf.h",
+    "util/u_vertex_state_cache.c",
+    "util/u_vertex_state_cache.h",
+    "util/u_video.h",
+    "util/u_viewport.h",
+  ]
+
+  configs = [
+    ":build_config",
+    "//build/config:Wno-strict-prototypes",
+    "$mesa_build_root:build_config",
+  ]
+}
+
+config("build_config") {
+  include_dirs = [
+    "$mesa_build_root/include/",
+    "$mesa_build_root/src/compiler/nir/",
+    "$mesa_build_root/src/gallium/auxiliary/",
+    "$mesa_build_root/src/gallium/include/",
+    "$mesa_build_root/src/util/",
+    "$mesa_build_root/src/",
+    "$target_gen_dir",
+  ]
+
+  configs = [ "//third_party/mesa:LLVMHeader_config" ]
+}
+
+mesa_python_action("tr_util_gen") {
+  h_file = "$target_gen_dir/driver_trace/tr_util.h"
+  c_file = "$target_gen_dir/driver_trace/tr_util.c"
+
+  outputs = [
+    h_file,
+    c_file,
+  ]
+
+  script = "driver_trace/enums2names.py"
+
+  inputs = [ "$mesa_build_root/src/gallium/include/pipe/p_defines.h" ] +
+           third_party_mako_srcs
+
+  args = [
+    rebase_path("$mesa_build_root", root_build_dir) +
+        "/src/gallium/include/pipe/p_defines.h",
+    "-C",
+    rebase_path(c_file, root_build_dir),
+    "-H",
+    rebase_path(h_file, root_build_dir),
+    "-I",
+    "tr_util.h",
+  ]
+}
+
+mesa_python_action("u_indices_gen") {
+  output_path = "$target_gen_dir/indices/u_indices_gen.c"
+
+  outputs = [ output_path ]
+  script = "indices/u_indices_gen.py"
+
+  args = [ rebase_path(output_path, root_build_dir) ]
+}
+
+mesa_python_action("u_tracepoints_gen") {
+  output_path = "$target_gen_dir/u_tracepoints.h"
+
+  script = "util/u_tracepoints.py"
+  outputs = [ output_path ]
+
+  args = [
+    "-p",
+    rebase_path("$mesa_build_root/src/util/perf", root_build_dir),
+    "-H",
+    rebase_path(output_path, root_build_dir),
+  ]
+}
+
+mesa_python_action("u_unfilled_gen") {
+  output_path = "$target_gen_dir/indices/u_unfilled_gen.c"
+
+  outputs = [ output_path ]
+  script = "indices/u_unfilled_gen.py"
+
+  args = [ rebase_path(output_path, root_build_dir) ]
+}
+
+config("gen_public_config") {
+  include_dirs = [
+    target_gen_dir,
+    "$mesa_build_root/include/",
+    "$mesa_build_root/src/",
+    "$mesa_build_root/src/gallium/auxiliary/",
+    "$mesa_build_root/src/gallium/auxiliary/driver_trace/",
+    "$mesa_build_root/src/gallium/include/",
+    "$mesa_build_root/src/util/",
+    "$target_gen_dir/driver_trace/",
+  ]
+}
+
+mesa_source_set("gen") {
+  public_configs = [ ":gen_public_config" ]
+
+  deps = [
+    ":u_indices_gen",
+    ":u_tracepoints_gen",
+    ":u_unfilled_gen",
+    ":tr_util_gen",
+  ]
+
+  sources = [
+    "$target_gen_dir/driver_trace/tr_util.c",
+    "$target_gen_dir/driver_trace/tr_util.h",
+    "$target_gen_dir/indices/u_indices_gen.c",
+    "$target_gen_dir/indices/u_unfilled_gen.c",
+    "$target_gen_dir/u_tracepoints.h",
+  ]
+}
diff --git a/src/gallium/auxiliary/driver_ddebug/dd_draw.c b/src/gallium/auxiliary/driver_ddebug/dd_draw.c
index 6dd4a12..c9256d3 100644
--- a/src/gallium/auxiliary/driver_ddebug/dd_draw.c
+++ b/src/gallium/auxiliary/driver_ddebug/dd_draw.c
@@ -38,6 +38,7 @@
 #include "tgsi/tgsi_scan.h"
 #include "util/os_time.h"
 #include <inttypes.h>
+#include <sys/stat.h>
 #include "pipe/p_config.h"
 
 void
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_fuchsia_memory_mapper.cpp b/src/gallium/auxiliary/gallivm/lp_bld_fuchsia_memory_mapper.cpp
new file mode 100644
index 0000000..3584bfb
--- /dev/null
+++ b/src/gallium/auxiliary/gallivm/lp_bld_fuchsia_memory_mapper.cpp
@@ -0,0 +1,259 @@
+/*
+ * Copyright © 2023 Google, LLC
+ *
+ * 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 "lp_bld_fuchsia_memory_mapper.hpp"
+
+#include <fidl/fuchsia.vulkan.loader/cpp/wire.h>
+#include <lib/component/incoming/cpp/protocol.h>
+
+#include <zircon/process.h>
+#include <zircon/status.h>
+#include <zircon/syscalls.h>
+#include "lib/zx/vmo.h"
+
+#include "llvm/Support/Process.h"
+
+using llvm::sys::MemoryBlock;
+using llvm::sys::Process;
+
+/* TODO(b/321122796): Replace fprintf() with Mesa-idiomatic logging. */
+
+namespace {
+
+static_assert(LLVM_ENABLE_THREADS);
+
+int getZirconProtectionFlags(unsigned Flags)
+{
+   switch (Flags) {
+   case llvm::sys::Memory::MF_READ:
+      return ZX_VM_FLAG_PERM_READ;
+   case llvm::sys::Memory::MF_WRITE:
+      return ZX_VM_FLAG_PERM_WRITE;
+   case llvm::sys::Memory::MF_READ | llvm::sys::Memory::MF_WRITE:
+      return ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE;
+   case llvm::sys::Memory::MF_READ | llvm::sys::Memory::MF_EXEC:
+      return ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_EXECUTE;
+   case llvm::sys::Memory::MF_READ | llvm::sys::Memory::MF_WRITE | llvm::sys::Memory::MF_EXEC:
+      return ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE | ZX_VM_FLAG_PERM_EXECUTE;
+   case llvm::sys::Memory::MF_EXEC:
+      return ZX_VM_FLAG_PERM_EXECUTE;
+   default:
+      /* TODO(b/321122796): use Mesa-idiomatic logging. */
+      llvm_unreachable("Illegal memory protection flag specified!");
+   }
+   // Provide a default return value as required by some compilers.
+   return 0;
+}
+
+}
+
+LavapipeMemoryMapper::LavapipeMemoryMapper()
+{
+    auto client_end_or = component::Connect<fuchsia_vulkan_loader::Loader>();
+    if (client_end_or.is_error()) {
+        fprintf(stderr, "LavapipeMemoryMapper failed to connect to Vulkan Loader: %s\n",
+                client_end_or.status_string());
+        return;
+    }
+
+    auto result = fidl::WireCall(*client_end_or)->GetVmexResource();
+    if (!result.ok()) {
+        fprintf(stderr,
+                "LavapipeMemoryMapper failed to get vmex from Vulkan Loader: %s\n",
+                result.status_string());
+        return;
+    }
+
+    vmex_ = std::move(result.value().resource);
+    if (!vmex_) {
+        fprintf(stderr, "LavapipeMemoryMapper VMEX request succeeded but it is NULL!\n");
+    }
+}
+
+llvm::sys::MemoryBlock
+LavapipeMemoryMapper::allocateMappedMemory(llvm::SectionMemoryManager::AllocationPurpose Purpose, 
+                                           size_t NumBytes,
+                                           const llvm::sys::MemoryBlock* const NearBlock,
+                                           unsigned Flags, std::error_code& EC)
+{
+    allocation_count_++;
+
+    if (allocation_count_ % 100 == 0) {
+        fprintf(stderr, "Lavapipe-LLVM allocations: %zu  releases: %zu  outstanding: %zi\n",
+                allocation_count_, release_count_, allocation_count_ - release_count_);
+    }
+
+    EC = std::error_code();
+    if (NumBytes == 0) {
+        fprintf(stderr, "LavapipeMemoryManager::allocateMappedMemory: NumBytes == 0\n");
+
+        return MemoryBlock();
+    }
+
+    int Protect = getZirconProtectionFlags(Flags);
+    if (Purpose == llvm::SectionMemoryManager::AllocationPurpose::Code) {
+        Protect |= ZX_VM_FLAG_PERM_EXECUTE;
+    }
+
+    // Use near hint (if available) and the page size to set a page-aligned starting address.
+    uintptr_t Start =
+        NearBlock ? reinterpret_cast<uintptr_t>(NearBlock->base()) + NearBlock->allocatedSize()
+                    : 0;
+    static const size_t PageSize = Process::getPageSizeEstimate();
+    const size_t NumPages = (NumBytes + PageSize - 1) / PageSize;
+    const size_t MappingSize = PageSize * NumPages;
+
+    if (Start && Start % PageSize)
+        Start += PageSize - Start % PageSize;
+
+    zx_handle_t VMO;
+    zx_status_t status = _zx_vmo_create(MappingSize, 0, &VMO);
+    if (status != ZX_OK) {
+        EC = std::error_code(status, std::generic_category());
+
+        fprintf(stderr,
+                "LavapipeMemoryManager::allocateMappedMemory: error in zx_vmo_create: %s\n",
+                zx_status_get_string(status));
+
+        return MemoryBlock();
+    }
+
+    if (Protect & ZX_VM_FLAG_PERM_EXECUTE) {
+        status = zx_vmo_replace_as_executable(VMO, vmex_.get(), &VMO);
+        if (status != ZX_OK) {
+            fprintf(stderr,
+                    "LavapipeMemoryManager::allocateMappedMemory: "
+                    "zx_vmo_replace_as_executable() failed: %s\n", zx_status_get_string(status));
+
+            EC = std::error_code(status, std::generic_category());
+            return MemoryBlock();
+        }
+    }
+
+    /* If anything below here fails, delete the VMO before returning to avoid leakage. */
+    zx::vmo VMO_raii(VMO);
+
+    const char* vmo_name = "[lavapipe-llvm]";
+    status = zx_object_set_property(VMO, ZX_PROP_NAME, vmo_name, strlen(vmo_name));
+    if (status != ZX_OK) {
+        // Handle error.  This isn't good, but it's not a show-stopper.
+        fprintf(stderr, "LavapipeMemoryManager::allocateMappedMemory: failed to set VMO name");
+    }
+
+    uintptr_t Addr;
+    status =
+        zx_vmar_map(_zx_vmar_root_self(), /*options=*/Protect, /*vmar_offset=*/0, /*vmo=*/VMO,
+                    /*vmo_offset=*/0, /*len=*/MappingSize, /*mapped_address=*/&Addr);
+    if (status != ZX_OK) {
+        if (NearBlock) { // Try again without a near hint
+            fprintf(stderr,
+                    "LavapipeMemoryManager::allocateMappedMemory: retrying without near "
+                    "hint after error: %s\n",
+                    zx_status_get_string(status));
+            return allocateMappedMemory(Purpose, NumBytes, nullptr, Flags, EC);
+        }
+
+        EC = std::error_code(status, std::generic_category());
+
+        fprintf(stderr,
+                "LavapipeMemoryManager::allocateMappedMemory: mapping failed with error: %s "
+                "root-vmar: %d _root-vmar: %d \n",
+                zx_status_get_string(status), zx_vmar_root_self(), _zx_vmar_root_self());
+
+        return MemoryBlock();
+    }
+
+    MemoryBlock Result(reinterpret_cast<void*>(Addr), MappingSize, Flags);
+
+    // Rely on protectMappedMemory to invalidate instruction cache.
+    if (Flags & llvm::sys::Memory::MF_EXEC) {
+        EC = protectMappedMemory(Result, Flags);
+        if (EC != std::error_code()) {
+            fprintf(stderr,
+                    "LavapipeMemoryManager::allocateMappedMemory: failed to protect memory: %d\n",
+                    EC.value());
+
+            return MemoryBlock();
+        }
+    }
+
+    return Result;
+}
+
+std::error_code
+LavapipeMemoryMapper::protectMappedMemory(const llvm::sys::MemoryBlock& Block, unsigned Flags)
+{
+    if (!Flags) {
+        fprintf(stderr, "LavapipeMemoryManager::protectMappedMemory failed because no flags set\n");
+
+        return std::error_code(EINVAL, std::generic_category());
+    }
+
+    static const llvm::Align PageSize = llvm::Align(Process::getPageSizeEstimate());
+    if (Block.base() == nullptr || Block.allocatedSize() == 0) {
+        fprintf(stderr,
+                "LavapipeMemoryManager::protectMappedMemory failed because "
+                "address or allocated size is zero\n");
+
+        return std::error_code();
+    }
+
+    int Protect = getZirconProtectionFlags(Flags);
+    uintptr_t Start = alignAddr((const uint8_t*)Block.base() - PageSize.value() + 1, PageSize);
+    uintptr_t End = alignAddr((const uint8_t*)Block.base() + Block.allocatedSize(), PageSize);
+
+    bool InvalidateCache = (Flags & llvm::sys::Memory::MF_EXEC);
+
+#if defined(__arm__) || defined(__aarch64__)
+    // Certain ARM implementations treat icache clear instruction as a memory read,
+    // and CPU segfaults on trying to clear cache on !PROT_READ page.  Therefore we need
+    // to temporarily add PROT_READ for the sake of flushing the instruction caches.
+    if (InvalidateCache && !(Protect & PROT_READ)) {
+        Memory::InvalidateInstructionCache(Block.base(), Block.allocatedSize());
+        InvalidateCache = false;
+    }
+#endif
+
+    zx_status_t status = zx_vmar_protect(_zx_vmar_root_self(), /*options=*/Protect,
+                                        /*addr=*/(uintptr_t)Start, /*len=*/End - Start);
+    if (status != ZX_OK) {
+        fprintf(stderr,
+            "LavapipeMemoryManager::protectMappedMemory: zx_vmar_protect() failed with error: "
+            "%s   options: %u   addr: %p  len: %p\n",
+            zx_status_get_string(status), Protect, (void*)Start, (void*)(End - Start));
+
+        return std::error_code(status, std::generic_category());
+    }
+
+    if (Flags & llvm::sys::Memory::MF_EXEC)
+        llvm::sys::Memory::InvalidateInstructionCache(Block.base(), Block.allocatedSize());
+
+    return std::error_code();
+}
+
+std::error_code LavapipeMemoryMapper::releaseMappedMemory(llvm::sys::MemoryBlock& M)
+{
+    release_count_++;
+
+    return llvm::sys::Memory::releaseMappedMemory(M);
+}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_fuchsia_memory_mapper.hpp b/src/gallium/auxiliary/gallivm/lp_bld_fuchsia_memory_mapper.hpp
new file mode 100644
index 0000000..7f2c0d5
--- /dev/null
+++ b/src/gallium/auxiliary/gallivm/lp_bld_fuchsia_memory_mapper.hpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright © 2023 Google, LLC
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include <llvm/ExecutionEngine/SectionMemoryManager.h>
+
+#include <lib/zx/resource.h>
+
+#include <cstddef>
+#include <system_error>
+
+class LavapipeMemoryMapper : public llvm::SectionMemoryManager::MemoryMapper {
+public:
+   LavapipeMemoryMapper();
+
+   llvm::sys::MemoryBlock
+   allocateMappedMemory(llvm::SectionMemoryManager::AllocationPurpose Purpose, size_t NumBytes,
+                        const llvm::sys::MemoryBlock* const NearBlock, unsigned Flags,
+                        std::error_code& EC) override;
+
+   std::error_code protectMappedMemory(const llvm::sys::MemoryBlock& Block,
+                                       unsigned Flags) override;
+
+   std::error_code releaseMappedMemory(llvm::sys::MemoryBlock& M) override;
+
+private:
+   zx::resource vmex_;
+   // TODO(b/321122796): temporary debugging to find potential memory leaks.  Can be removed.
+   size_t allocation_count_ = 0;
+   size_t release_count_ = 0;
+};
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
index 0d6a261..89c069b 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
+++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
@@ -100,6 +100,14 @@
 #include "lp_bld_misc.h"
 #include "lp_bld_debug.h"
 
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+#include "lp_bld_fuchsia_memory_mapper.hpp"
+#include <zircon/process.h>
+#include <zircon/status.h>
+#include <zircon/syscalls.h>
+#include "lib/zx/vmo.h"
+#endif
+
 namespace {
 
 class LLVMEnsureMultithreaded {
@@ -114,7 +122,7 @@
 
 static LLVMEnsureMultithreaded lLVMEnsureMultithreaded;
 
-}
+}  // namespace
 
 static once_flag init_native_targets_once_flag = ONCE_FLAG_INIT;
 
@@ -366,7 +374,7 @@
    builder.setEngineKind(EngineKind::JIT)
           .setErrorStr(&Error)
           .setTargetOptions(options)
-          .setOptLevel((CodeGenOpt::Level)OptLevel);
+          .setOptLevel(CodeGenOpt::getLevel(OptLevel).value());
 
 #ifdef _WIN32
     /*
@@ -576,8 +584,15 @@
 LLVMMCJITMemoryManagerRef
 lp_get_default_memory_manager()
 {
-   BaseMemoryManager *mm;
-   mm = new llvm::SectionMemoryManager();
+#if defined(VK_USE_PLATFORM_FUCHSIA)
+   static llvm::SectionMemoryManager::MemoryMapper* mapper = new LavapipeMemoryMapper();
+#else
+   constexpr llvm::SectionMemoryManager::MemoryMapper* mapper = nullptr;
+#endif
+
+   BaseMemoryManager* mm;
+   mm = new llvm::SectionMemoryManager(mapper);
+
    return reinterpret_cast<LLVMMCJITMemoryManagerRef>(mm);
 }
 
diff --git a/src/gallium/auxiliary/pipe-loader/BUILD.gn b/src/gallium/auxiliary/pipe-loader/BUILD.gn
new file mode 100644
index 0000000..ff975c9
--- /dev/null
+++ b/src/gallium/auxiliary/pipe-loader/BUILD.gn
@@ -0,0 +1,72 @@
+# Copyright 2023 Google, LLC
+#
+# 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.
+
+import("../../../../mesa.gni")
+
+# Allow multiple source sets to be compiled with the same source code but different configs.
+pipe_loader_sources = [
+  "driinfo_gallium.h",
+  "pipe_loader.c",
+  "pipe_loader.h",
+  "pipe_loader_priv.h",
+  "pipe_loader_sw.c",
+]
+
+pipe_loader_deps = [
+  "$mesa_build_root/src/gallium/winsys/sw/dri",
+  "$mesa_build_root/src/gallium/winsys/sw/null",
+  "$mesa_build_root/src/gallium/winsys/sw/wrapper",
+  "$mesa_build_root/src/util:xmlconfig",
+]
+
+config("pipe-loader-config-base") {
+  include_dirs = [
+    "$mesa_build_root/include/",
+    "$mesa_build_root/src/",
+    "$mesa_build_root/src/gallium/auxiliary/",
+    "$mesa_build_root/src/gallium/include/",
+    "$mesa_build_root/src/gallium/winsys/",
+  ]
+
+  configs = [ "$mesa_build_root/src/gallium:build_config" ]
+}
+
+mesa_source_set("pipe-loader") {
+  sources = pipe_loader_sources
+  deps = pipe_loader_deps
+  configs = [ ":pipe-loader-config-base" ]
+}
+
+config("pipe-loader-config-llvmpipe") {
+  defines = [ "GALLIUM_LLVMPIPE" ]
+}
+
+# A specialized pipe-loader with the same source code but configured differently.  This accomplishes
+# the same goal as //src/gallium/drivers/llvmpipe/meson.build, where the "driver_swrast" is replaced
+# with a modified version.  GN is less flexible than Meson in this regard, so we take this approach.
+mesa_source_set("pipe-loader-llvmpipe") {
+  sources = pipe_loader_sources
+  deps = pipe_loader_deps
+  configs = [
+    ":pipe-loader-config-base",
+    ":pipe-loader-config-llvmpipe",
+  ]
+}
diff --git a/src/gallium/auxiliary/rtasm/rtasm_execmem.c b/src/gallium/auxiliary/rtasm/rtasm_execmem.c
index 7fd834e..646514f 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_execmem.c
+++ b/src/gallium/auxiliary/rtasm/rtasm_execmem.c
@@ -46,7 +46,7 @@
 #include <windows.h>
 #endif
 
-#if defined(PIPE_OS_UNIX)
+#if defined(PIPE_OS_UNIX) || defined(PIPE_OS_FUCHSIA)
 
 
 /*
diff --git a/src/gallium/drivers/llvmpipe/BUILD.gn b/src/gallium/drivers/llvmpipe/BUILD.gn
new file mode 100644
index 0000000..d1a7c70
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/BUILD.gn
@@ -0,0 +1,139 @@
+# Copyright 2023 Google, LLC
+#
+# 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.
+
+import("../../../../mesa.gni")
+
+config("llvmpipe_config") {
+  include_dirs = [
+    "$root_gen_dir/third_party/mesa/src/",
+    "$mesa_build_root/include/",
+    "$mesa_build_root/src/compiler/nir/",
+    "$mesa_build_root/src/gallium/auxiliary/",
+    "$mesa_build_root/src/gallium/include/",
+    "$mesa_build_root/src/",
+  ]
+
+  # Suppress warnings.
+  configs = [
+    "//build/config:Wno-strict-prototypes",
+    "//third_party/mesa:LLVMHeader_config",
+  ]
+}
+
+mesa_source_set("llvmpipe") {
+  configs = [
+    "$mesa_build_root:build_config",
+    ":llvmpipe_config",
+  ]
+
+  deps = [ "$mesa_build_root/src/compiler/nir" ]
+
+  sources = [
+    "lp_bld_alpha.c",
+    "lp_bld_alpha.h",
+    "lp_bld_blend.c",
+    "lp_bld_blend.h",
+    "lp_bld_blend_aos.c",
+    "lp_bld_blend_logicop.c",
+    "lp_bld_depth.c",
+    "lp_bld_depth.h",
+    "lp_bld_interp.c",
+    "lp_bld_interp.h",
+    "lp_clear.c",
+    "lp_clear.h",
+    "lp_context.c",
+    "lp_context.h",
+    "lp_cs_tpool.c",
+    "lp_cs_tpool.h",
+    "lp_debug.h",
+    "lp_draw_arrays.c",
+    "lp_fence.c",
+    "lp_fence.h",
+    "lp_flush.c",
+    "lp_flush.h",
+    "lp_jit.c",
+    "lp_jit.h",
+    "lp_limits.h",
+    "lp_linear.c",
+    "lp_linear_fastpath.c",
+    "lp_linear_interp.c",
+    "lp_linear_sampler.c",
+    "lp_memory.c",
+    "lp_memory.h",
+    "lp_perf.c",
+    "lp_perf.h",
+    "lp_public.h",
+    "lp_query.c",
+    "lp_query.h",
+    "lp_rast.c",
+    "lp_rast.h",
+    "lp_rast_debug.c",
+    "lp_rast_linear.c",
+    "lp_rast_linear_fallback.c",
+    "lp_rast_priv.h",
+    "lp_rast_rect.c",
+    "lp_rast_tri.c",
+    "lp_rast_tri_tmp.h",
+    "lp_scene.c",
+    "lp_scene.h",
+    "lp_scene_queue.c",
+    "lp_scene_queue.h",
+    "lp_screen.c",
+    "lp_screen.h",
+    "lp_setup.c",
+    "lp_setup.h",
+    "lp_setup_analysis.c",
+    "lp_setup_context.h",
+    "lp_setup_line.c",
+    "lp_setup_point.c",
+    "lp_setup_rect.c",
+    "lp_setup_tri.c",
+    "lp_setup_vbuf.c",
+    "lp_state.h",
+    "lp_state_blend.c",
+    "lp_state_clip.c",
+    "lp_state_cs.c",
+    "lp_state_cs.h",
+    "lp_state_derived.c",
+    "lp_state_fs.c",
+    "lp_state_fs.h",
+    "lp_state_fs_analysis.c",
+    "lp_state_fs_fastpath.c",
+    "lp_state_fs_linear.c",
+    "lp_state_fs_linear_llvm.c",
+    "lp_state_gs.c",
+    "lp_state_rasterizer.c",
+    "lp_state_sampler.c",
+    "lp_state_setup.c",
+    "lp_state_setup.h",
+    "lp_state_so.c",
+    "lp_state_surface.c",
+    "lp_state_tess.c",
+    "lp_state_vertex.c",
+    "lp_state_vs.c",
+    "lp_surface.c",
+    "lp_surface.h",
+    "lp_tex_sample.c",
+    "lp_tex_sample.h",
+    "lp_texture.c",
+    "lp_texture.h",
+  ]
+}
diff --git a/src/gallium/frontends/lavapipe/BUILD.gn b/src/gallium/frontends/lavapipe/BUILD.gn
new file mode 100644
index 0000000..2929312
--- /dev/null
+++ b/src/gallium/frontends/lavapipe/BUILD.gn
@@ -0,0 +1,138 @@
+# Copyright 2023 Google, LLC
+#
+# 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.
+
+import("//third_party/mako/py_srcs.gni")
+import("../../../../mesa.gni")
+
+mesa_python_action("lvp_entrypoints") {
+  outputs = [
+    "$target_gen_dir/lvp_entrypoints.h",
+    "$target_gen_dir/lvp_entrypoints.c",
+  ]
+
+  script = "$mesa_build_root/src/vulkan/util/vk_entrypoints_gen.py"
+
+  inputs = [
+             "$mesa_build_root/src/vulkan/util/vk_dispatch_table_gen.py",
+             "$mesa_build_root/src/vulkan/util/vk_extensions.py",
+             "$mesa_build_root/src/vulkan/util/vk_entrypoints.py",
+             "$mesa_build_root/src/vulkan/registry/vk.xml",
+           ] + third_party_mako_srcs
+
+  args = [
+    "--xml",
+    rebase_path("$mesa_build_root", root_build_dir) +
+        "/src/vulkan/registry/vk.xml",
+    "--proto",
+    "--weak",
+    "--out-h",
+    rebase_path("$target_gen_dir/lvp_entrypoints.h", root_build_dir),
+    "--out-c",
+    rebase_path("$target_gen_dir/lvp_entrypoints.c", root_build_dir),
+    "--prefix",
+    "lvp",
+  ]
+}
+
+config("lavapipe_config") {
+  include_dirs = [
+    "$root_gen_dir/third_party/mesa/src/compiler/nir/",
+    "$root_gen_dir/third_party/mesa/src/gallium/frontends/lavapipe/",
+    "$root_gen_dir/third_party/mesa/src/vulkan/runtime/",
+    "$root_gen_dir/third_party/mesa/src/vulkan/util/",
+    "$mesa_build_root/include/",
+    "$mesa_build_root/src/compiler/",
+    "$mesa_build_root/src/compiler/nir/",
+    "$mesa_build_root/src/gallium/auxiliary/",
+    "$mesa_build_root/src/gallium/drivers/",
+    "$mesa_build_root/src/gallium/include/",
+    "$mesa_build_root/src/gallium/winsys/",
+    "$mesa_build_root/src/util/",
+    "$mesa_build_root/src/",
+    "$mesa_build_root/src/vulkan/util/",
+  ]
+
+  defines = [
+    # Unnecessary because we hardcode GALLIUM_STATIC_TARGETS=1.
+    "PIPE_SEARCH_DIR=\"UNNECESSARY\"",
+
+    # TODO(b/321122796): otherwise get "use of undeclared identifier 'NULL'" in u_dl.c etc.
+    # Is there some better way to define this?  If we do decide to define NULL (vs e.g. adding
+    # a header include), is this the best place?  Probably, since this is closest to where it's
+    # needed.
+    "NULL=0",
+
+    # So that sw_screen_create_vk() is customized to use lavapipe.
+    "GALLIUM_LLVMPIPE",
+  ]
+
+  # Suppress warnings.
+  configs = [
+    "//build/config:Wno-unused-but-set-variable",
+    "//build/config:Wno-strict-prototypes",
+    "//third_party/mesa:LLVMHeader_config",
+  ]
+}
+
+mesa_source_set("lavapipe") {
+  public_deps = [
+    "$mesa_build_root/src/compiler",
+    "$mesa_build_root/src/vulkan/wsi",
+  ]
+
+  public_configs = [ ":lavapipe_config" ]
+
+  deps = [
+    ":lvp_entrypoints",
+    "$mesa_build_root/src:sha1",
+    "$mesa_build_root/src/compiler/nir",
+    "$mesa_build_root/src/gallium/auxiliary",
+    "$mesa_build_root/src/gallium/auxiliary/pipe-loader:pipe-loader-llvmpipe",
+    "$mesa_build_root/src/util",
+    "$mesa_build_root/src/vulkan/runtime",
+    "$mesa_build_root/src/vulkan/util",
+  ]
+
+  sources = [
+    # target.c is not used by our sibling meson.build, but rather by
+    # //mesa/src/gallium/targets/lavapipe/meson.build.  We include it here because it's not worth
+    # creating another BUILD.gn for a single file.
+    "$mesa_build_root/src/gallium/targets/lavapipe/target.c",
+    "$target_gen_dir/lvp_entrypoints.c",
+    "$target_gen_dir/lvp_entrypoints.h",
+    "lvp_cmd_buffer.c",
+    "lvp_descriptor_set.c",
+    "lvp_device.c",
+    "lvp_execute.c",
+    "lvp_formats.c",
+    "lvp_image.c",
+    "lvp_inline_uniforms.c",
+    "lvp_lower_input_attachments.c",
+    "lvp_lower_vulkan_resource.c",
+    "lvp_lower_vulkan_resource.h",
+    "lvp_pipe_sync.c",
+    "lvp_pipeline.c",
+    "lvp_pipeline_cache.c",
+    "lvp_query.c",
+    "lvp_util.c",
+    "lvp_wsi.c",
+  ]
+}
diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h
index f35a7dc..acbaeb0 100644
--- a/src/gallium/include/pipe/p_config.h
+++ b/src/gallium/include/pipe/p_config.h
@@ -192,4 +192,8 @@
 #define PIPE_OS_CYGWIN
 #endif
 
+#if DETECT_OS_FUCHSIA
+#define PIPE_OS_FUCHSIA
+#endif
+
 #endif /* P_CONFIG_H_ */
diff --git a/src/gallium/winsys/sw/dri/BUILD.gn b/src/gallium/winsys/sw/dri/BUILD.gn
new file mode 100644
index 0000000..2779f49
--- /dev/null
+++ b/src/gallium/winsys/sw/dri/BUILD.gn
@@ -0,0 +1,36 @@
+# Copyright 2023 Google, LLC
+#
+# 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.
+
+import("../../../../../mesa.gni")
+
+mesa_source_set("dri") {
+  sources = [
+    "dri_sw_winsys.c",
+    "dri_sw_winsys.h",
+  ]
+
+  include_dirs = [
+    "$mesa_build_root/include/",
+    "$mesa_build_root/src/",
+    "$mesa_build_root/src/gallium/auxiliary/",
+    "$mesa_build_root/src/gallium/include/",
+  ]
+}
diff --git a/src/gallium/winsys/sw/null/BUILD.gn b/src/gallium/winsys/sw/null/BUILD.gn
new file mode 100644
index 0000000..7db06cb
--- /dev/null
+++ b/src/gallium/winsys/sw/null/BUILD.gn
@@ -0,0 +1,35 @@
+# Copyright 2023 Google, LLC
+#
+# 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.
+
+import("../../../../../mesa.gni")
+
+mesa_source_set("null") {
+  sources = [
+    "null_sw_winsys.c",
+    "null_sw_winsys.h",
+  ]
+
+  include_dirs = [
+    "$mesa_build_root/src/",
+    "$mesa_build_root/src/gallium/auxiliary/",
+    "$mesa_build_root/src/gallium/include/",
+  ]
+}
diff --git a/src/gallium/winsys/sw/wrapper/BUILD.gn b/src/gallium/winsys/sw/wrapper/BUILD.gn
new file mode 100644
index 0000000..d0a7480
--- /dev/null
+++ b/src/gallium/winsys/sw/wrapper/BUILD.gn
@@ -0,0 +1,36 @@
+# Copyright 2023 Google, LLC
+#
+# 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.
+
+import("../../../../../mesa.gni")
+
+mesa_source_set("wrapper") {
+  sources = [
+    "wrapper_sw_winsys.c",
+    "wrapper_sw_winsys.h",
+  ]
+
+  include_dirs = [
+    "$mesa_build_root/include/",
+    "$mesa_build_root/src/",
+    "$mesa_build_root/src/gallium/auxiliary/",
+    "$mesa_build_root/src/gallium/include/",
+  ]
+}
diff --git a/src/intel/vulkan/anv_batch_chain.c b/src/intel/vulkan/anv_batch_chain.c
index 92176cf..cd01b34 100644
--- a/src/intel/vulkan/anv_batch_chain.c
+++ b/src/intel/vulkan/anv_batch_chain.c
@@ -1376,10 +1376,11 @@
       if (!(sync->flags & VK_SYNC_IS_TIMELINE))
          value = 0;
 
-      return anv_execbuf_add_syncobj(device, execbuf, syncobj->syncobj,
+      return anv_execbuf_add_syncobj(device, execbuf, syncobj,
                                      is_signal ? I915_EXEC_FENCE_SIGNAL :
                                                  I915_EXEC_FENCE_WAIT,
                                      value);
+   }
 #endif
    unreachable("Invalid sync type");
 }
diff --git a/src/util/BUILD.gn b/src/util/BUILD.gn
index 91a2627..2580664 100644
--- a/src/util/BUILD.gn
+++ b/src/util/BUILD.gn
@@ -30,6 +30,13 @@
   ]
 }
 
+config("build_config") {
+  include_dirs = [
+    "$mesa_build_root/src/gallium/include/",
+    "$mesa_build_root/src/",
+  ]
+}
+
 mesa_source_set("headers") {
   public_configs = [ ":util_public_config" ]
 
@@ -97,37 +104,145 @@
   public_configs = [ ":util_public_config" ]
 
   sources = [
-    "anon_file.h",
+    "bigmath.h",
+    "bitscan.c",
+    "bitscan.h",
+    "bitset.h",
     "blob.c",
+    "blob.h",
     "build_id.c",
+    "build_id.h",
+    "cnd_monotonic.h",
+    "compiler.h",
+    "compress.c",
+    "compress.h",
+    "crc32.c",
+    "crc32.h",
+    "dag.c",
+    "disk_cache.c",
+    "disk_cache.h",
+    "disk_cache_os.c",
+    "disk_cache_os.h",
     "double.c",
+    "double.h",
+    "enum_operators.h",
     "fast_idiv_by_const.c",
+    "fast_idiv_by_const.h",
+    "format_r11g11b10f.h",
+    "format_rgb9e5.h",
+    "format_srgb.h",
+    "fossilize_db.c",
+    "fossilize_db.h",
+    "futex.h",
     "half_float.c",
+    "half_float.h",
     "hash_table.c",
+    "hash_table.h",
+    "list.h",
     "log.c",
+    "macros.h",
     "memstream.c",
+    "memstream.h",
     "mesa-sha1.c",
+    "mesa-sha1.h",
+    "mesa_cache_db.c",
+    "mesa_cache_db.h",
     "os_file.c",
+    "os_memory_fd.c",
     "os_misc.c",
+    "os_misc.h",
+    "os_socket.c",
+    "os_socket.h",
     "os_time.c",
+    "os_time.h",
     "perf/u_trace.c",
+    "perf/u_trace.h",
+    "perf/u_trace_priv.h",
+    "ptralloc.h",
     "ralloc.c",
+    "ralloc.h",
+    "rand_xor.c",
+    "rand_xor.h",
+    "rb_tree.c",
+    "rb_tree.h",
     "register_allocate.c",
+    "register_allocate.h",
     "rgtc.c",
+    "rgtc.h",
+    "rounding.h",
+    "rwlock.c",
+    "rwlock.h",
     "set.c",
+    "set.h",
     "sha1/sha1.c",
+    "sha1/sha1.h",
+    "simple_mtx.c",
+    "simple_mtx.h",
+    "slab.c",
+    "slab.h",
     "softfloat.c",
+    "softfloat.h",
     "sparse_array.c",
+    "sparse_array.h",
+    "string_buffer.c",
+    "string_buffer.h",
+    "strndup.h",
     "strtod.c",
+    "strtod.h",
+    "texcompress_rgtc_tmp.h",
+    "timespec.h",
+    "u_atomic.c",
+    "u_atomic.h",
+    "u_call_once.c",
+    "u_call_once.h",
     "u_cpu_detect.c",
+    "u_cpu_detect.h",
     "u_debug.c",
+    "u_debug.h",
+    "u_debug_describe.c",
+    "u_debug_describe.h",
+    "u_debug_memory.c",
+    "u_debug_refcnt.c",
+    "u_debug_refcnt.h",
+    "u_dl.c",
+    "u_dl.h",
+    "u_dynarray.h",
+    "u_endian.h",
+    "u_fifo.h",
+    "u_hash_table.c",
+    "u_hash_table.h",
+    "u_idalloc.c",
+    "u_idalloc.h",
+    "u_math.c",
+    "u_math.h",
+    "u_memset.h",
+    "u_mm.c",
+    "u_mm.h",
+
+    # TODO(b/301509045): enable Perfetto support.
+    # "u_perfetto.c",
+    # "u_perfetto.h",
+    "u_pointer.h",
     "u_printf.c",
+    "u_printf.h",
     "u_process.c",
+    "u_process.h",
+    "u_qsort.cpp",
+    "u_qsort.h",
     "u_queue.c",
+    "u_queue.h",
+    "u_string.h",
     "u_thread.c",
+    "u_thread.h",
     "u_vector.c",
+    "u_vector.h",
     "u_worklist.c",
+    "u_worklist.h",
+    "vl_rbsp.h",
+    "vl_vlc.h",
     "vma.c",
+    "vma.h",
+    "xxhash.h",
   ]
 
   deps = [ "$mesa_build_root/src/c11" ]
@@ -148,9 +263,21 @@
       sources += [ "futex.c" ]
     }
 
-    sources += [ "anon_file.c" ]
+    sources += [
+      "anon_file.c",
+      "anon_file.h",
+    ]
   }
+
+  # Would need to do something different for Android.  See meson.build
+  sources += [
+    "u_debug_stack.c",
+    "u_debug_symbol.c",
+    "u_debug_symbol.h",
+  ]
+
   configs = [
+    ":build_config",
     "//build/config:Wno-conversion",
     "//build/config:Wno-strict-prototypes",
   ]
@@ -167,11 +294,36 @@
   public_configs = [ ":util_public_config" ]
 }
 
+mesa_source_set("xmlconfig") {
+  sources = [
+    "xmlconfig.c",
+    "xmlconfig.h",
+  ]
+
+  deps = [
+    ":gen",
+    "//third_party/expat",
+  ]
+
+  configs = [ ":util_public_config" ]
+}
+
 mesa_python_stdout_to_file_action("format_srgb") {
   output = "format_srgb.c"
   script = "format_srgb.py"
 }
 
+mesa_python_action("driconf_static") {
+  output_name = "driconf_static.h"
+  script = "driconf_static.py"
+  inputs = [ "00-mesa-defaults.conf" ]
+  outputs = [ "$target_gen_dir/$output_name" ]
+  args = [
+    rebase_path(".") + "/00-mesa-defaults.conf",
+    rebase_path(target_gen_dir, root_build_dir) + "/$output_name",
+  ]
+}
+
 config("gen_public_config") {
   include_dirs = [ target_gen_dir ]
 }
@@ -180,6 +332,7 @@
   public_configs = [ ":gen_public_config" ]
 
   deps = [
+    ":driconf_static",
     ":format_srgb",
     "$mesa_build_root/include:c_compat",
   ]
@@ -187,5 +340,8 @@
   include_dirs = [ "." ]
 
   sources = [ "$target_gen_dir/format_srgb.c" ]
-  configs = [ "//build/config:Wno-conversion" ]
+  configs = [
+    ":build_config",
+    "//build/config:Wno-conversion",
+  ]
 }
diff --git a/src/util/log.c b/src/util/log.c
index 63aa124..2076f95 100644
--- a/src/util/log.c
+++ b/src/util/log.c
@@ -111,6 +111,7 @@
 #if !DETECT_OS_WINDOWS && !__Fuchsia__
    funlockfile(stderr);
 #endif
+
 #endif
 }
 
diff --git a/src/util/u_dl.c b/src/util/u_dl.c
index c0c0cbc..171106a 100644
--- a/src/util/u_dl.c
+++ b/src/util/u_dl.c
@@ -29,7 +29,7 @@
 
 #include "detect_os.h"
 
-#if DETECT_OS_UNIX
+#if DETECT_OS_UNIX || DETECT_OS_FUCHSIA
 #include <dlfcn.h>
 #endif
 #if DETECT_OS_WINDOWS
@@ -43,7 +43,7 @@
 struct util_dl_library *
 util_dl_open(const char *filename)
 {
-#if DETECT_OS_UNIX
+#if DETECT_OS_UNIX || DETECT_OS_FUCHSIA
    return (struct util_dl_library *)dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
 #elif DETECT_OS_WINDOWS
    return (struct util_dl_library *)LoadLibraryA(filename);
@@ -57,7 +57,7 @@
 util_dl_get_proc_address(struct util_dl_library *library,
                          const char *procname)
 {
-#if DETECT_OS_UNIX
+#if DETECT_OS_UNIX || DETECT_OS_FUCHSIA
    return (util_dl_proc) pointer_to_func(dlsym((void *)library, procname));
 #elif DETECT_OS_WINDOWS
    return (util_dl_proc)GetProcAddress((HMODULE)library, procname);
@@ -70,7 +70,7 @@
 void
 util_dl_close(struct util_dl_library *library)
 {
-#if DETECT_OS_UNIX
+#if DETECT_OS_UNIX || DETECT_OS_FUCHSIA
    dlclose((void *)library);
 #elif DETECT_OS_WINDOWS
    FreeLibrary((HMODULE)library);
@@ -83,7 +83,7 @@
 const char *
 util_dl_error(void)
 {
-#if DETECT_OS_UNIX
+#if DETECT_OS_UNIX || DETECT_OS_FUCHSIA
    return dlerror();
 #elif DETECT_OS_WINDOWS
    return "unknown error";
diff --git a/src/vulkan/runtime/BUILD.gn b/src/vulkan/runtime/BUILD.gn
index 6a00acb..14c5eb8 100644
--- a/src/vulkan/runtime/BUILD.gn
+++ b/src/vulkan/runtime/BUILD.gn
@@ -83,10 +83,10 @@
     "vk_deferred_operation.h",
     "vk_descriptor_set_layout.c",
     "vk_descriptor_set_layout.h",
-    "vk_descriptors.c",
-    "vk_descriptors.h",
     "vk_descriptor_update_template.c",
     "vk_descriptor_update_template.h",
+    "vk_descriptors.c",
+    "vk_descriptors.h",
     "vk_device.c",
     "vk_device.h",
     "vk_fence.c",
@@ -99,10 +99,10 @@
     "vk_image.h",
     "vk_instance.c",
     "vk_instance.h",
-    "vk_magma_syncobj.c",
-    "vk_magma_syncobj.h",
     "vk_log.c",
     "vk_log.h",
+    "vk_magma_syncobj.c",
+    "vk_magma_syncobj.h",
     "vk_nir.c",
     "vk_nir.h",
     "vk_object.c",
@@ -113,6 +113,8 @@
     "vk_pipeline.h",
     "vk_pipeline_cache.c",
     "vk_pipeline_cache.h",
+    "vk_pipeline_layout.c",
+    "vk_pipeline_layout.h",
     "vk_queue.c",
     "vk_queue.h",
     "vk_render_pass.c",
diff --git a/src/vulkan/runtime/meson.build b/src/vulkan/runtime/meson.build
index 3867bc92..5b275c1 100644
--- a/src/vulkan/runtime/meson.build
+++ b/src/vulkan/runtime/meson.build
@@ -56,8 +56,6 @@
   'vk_image.h',
   'vk_instance.c',
   'vk_instance.h',
-  'vk_magma_syncobj.c',
-  'vk_magma_syncobj.h',
   'vk_log.c',
   'vk_log.h',
   'vk_nir.c',
diff --git a/src/vulkan/runtime/vk_semaphore.c b/src/vulkan/runtime/vk_semaphore.c
index cee1bee..5e72140 100644
--- a/src/vulkan/runtime/vk_semaphore.c
+++ b/src/vulkan/runtime/vk_semaphore.c
@@ -47,8 +47,10 @@
    if (type->export_sync_file && semaphore_type == VK_SEMAPHORE_TYPE_BINARY)
       handle_types |= VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
 
+#if defined(USE_MAGMA)
    if (type->import_magma_handle)
       handle_types |= VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA;
+#endif
 
    return handle_types;
 }
@@ -65,8 +67,10 @@
    if (type->export_sync_file && semaphore_type == VK_SEMAPHORE_TYPE_BINARY)
       handle_types |= VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
 
+#if defined(USE_MAGMA)
    if (type->export_magma_handle)
       handle_types |= VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA;
+#endif
 
    return handle_types;
 }