Build support for Magma and Fuchsia

Bufmgr is stubbed.

Change-Id: Iad58459a1f4e443eaf58e3d5f1db8b7d8d6765bc
diff --git a/README.fuchsia.md b/README.fuchsia.md
new file mode 100644
index 0000000..f2cd137
--- /dev/null
+++ b/README.fuchsia.md
@@ -0,0 +1,41 @@
+# Intel media-driver on Fuchsia
+
+## Meta-data
+
+Name: media-driver
+URL: https://01.org/intel-media-for-linux
+License: MIT,X11
+License File: LICENSE.md
+Upstream Git: https://github.com/intel/media-driver
+Description: The Intel(R) Media Driver for VAAPI is a new VA-API (Video Acceleration API) user mode driver supporting hardware accelerated decoding, encoding, and video post processing for GEN based graphics hardware.
+
+## Build
+
+### Dependencies
+
+libva and gmmlib are needed to build the media-driver.  From Fuchsia root:
+
+mkdir -p third_party/intel
+git clone https://fuchsia.googlesource.com/third_party/github.com/intel/libva third_party/intel/libva
+git clone https://fuchsia.googlesource.com/third_party/github.com/intel/gmmlib third_party/intel/gmmlib
+git clone https://fuchsia.googlesource.com/third_party/github.com/intel/media-driver third_party/intel/media-driver
+
+### Command
+
+Add to fx set:
+
+--with //third_party/intel/media-driver/fuchsia:va-intel
+
+A GN action wraps fuchsia/build.sh, an out-of-tree build process based on the native build systems (meson and cmake).
+The out of tree build emits shared libraries which currently are imported into the GN build.
+Eventually the shared libraries will be made available in CIPD.
+
+### Flags
+
+For debug logging:
+
+--args intel_media_driver_debug=true
+
+## Usage
+
+VA entry points are provided by libva.so.  This library dynamically links to the client driver library, iHD_drv_video.so.
diff --git a/fuchsia/BUILD.gn b/fuchsia/BUILD.gn
new file mode 100644
index 0000000..2dfa250
--- /dev/null
+++ b/fuchsia/BUILD.gn
@@ -0,0 +1,101 @@
+# Copyright 2021 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+
+import("//build/components.gni")
+
+declare_args() {
+  intel_media_driver_debug = is_debug
+}
+
+va_install_root = "$root_out_dir/build-intel-media-driver/install"
+
+config("va-config") {
+  include_dirs = [ "$va_install_root/include" ]
+  libs = [ "$va_install_root/lib/libva.so.2" ]
+}
+
+resource("libva-resource") {
+  sources = [ "$va_install_root/lib/libva.so.2" ]
+  outputs = [ "lib/libva.so.2" ]
+}
+
+group("va") {
+  public_configs = [ ":va-config" ]
+  public_deps = [ ":libva-resource" ]
+}
+
+config("va-magma-config") {
+  include_dirs = [ "$va_install_root/include" ]
+  libs = [ "$va_install_root/lib/libva-magma.so.2" ]
+}
+
+resource("libva-magma-resource") {
+  sources = [ "$va_install_root/lib/libva-magma.so.2" ]
+  outputs = [ "lib/libva-magma.so.2" ]
+}
+
+group("va-magma") {
+  public_configs = [ ":va-magma-config" ]
+  public_deps = [
+    ":libva-magma-resource",
+    "//src/graphics/lib/magma/include:magma_abi",
+  ]
+}
+
+resource("gmmlib-resource") {
+  sources = [ "$va_install_root/lib/libigdgmm.so.11" ]
+  outputs = [ "lib/libigdgmm.so.11" ]
+}
+
+resource("va-intel-resource") {
+  sources = [ "$va_install_root/iHD_drv_video.so" ]
+  outputs = [ "lib/iHD_drv_video.so" ]
+}
+
+# Only have a copy of the action in one toolchain.
+if (current_toolchain == default_toolchain) {
+  action("out-of-tree-build") {
+    script = "build.sh"
+
+    outputs = [
+      "$va_install_root/lib/libva.so.2",
+      "$va_install_root/lib/libva-magma.so.2",
+      "$va_install_root/lib/libigdgmm.so.11",
+      "$va_install_root/iHD_drv_video.so",
+
+      # Placeholder is here just to force an incremental build
+      "$va_install_root/place_holder",
+    ]
+
+    fuchsia_dir = rebase_path("$root_build_dir/../..")
+    fuchsia_out_dir = rebase_path(root_out_dir)
+
+    args = [
+      fuchsia_dir,
+      fuchsia_out_dir,
+    ]
+
+    if (intel_media_driver_debug) {
+      args += [ "debug" ]
+    } else {
+      args += [ "release" ]
+    }
+
+    deps = [
+      "//sdk:zircon_sysroot_export",
+      "//src/graphics/lib/magma/src/libmagma:libmagma_complete",
+    ]
+  }
+}
+
+group("va-intel") {
+  public_deps = [
+    ":gmmlib-resource",
+    ":va",
+    ":va-intel-resource",
+    ":va-magma",
+  ]
+  deps = [ ":out-of-tree-build" ]
+}
diff --git a/fuchsia/build.sh b/fuchsia/build.sh
new file mode 100755
index 0000000..44edfb1
--- /dev/null
+++ b/fuchsia/build.sh
@@ -0,0 +1,97 @@
+#!/usr/bin/env bash
+set -e
+
+FUCHSIA_DIR=`realpath $1`
+FUCHSIA_OUT_DIR=`realpath $2`
+TARGET=$3
+
+SCRIPT_DIR=$FUCHSIA_DIR/third_party/intel/media-driver/fuchsia
+CLANG_DIR=$FUCHSIA_DIR/prebuilt/third_party/clang/linux-x64
+FUCHSIA_SHARED_OUT_DIR=$FUCHSIA_OUT_DIR/x64-shared
+SYSROOT_DIR=$FUCHSIA_OUT_DIR/sdk/exported/zircon_sysroot/arch/x64/sysroot
+OUT_DIR=$FUCHSIA_OUT_DIR/build-intel-media-driver
+
+if [[ "$TARGET" == "debug" ]]; then
+  echo "TARGET: $TARGET"
+elif [[ "$TARGET" == "release" ]]; then
+  echo "TARGET: $TARGET"
+else
+  echo "Unrecognized target: '$TARGET'"
+fi
+
+echo "FUCHSIA_DIR: $FUCHSIA_DIR"
+echo "SCRIPT_DIR: $SCRIPT_DIR"
+echo "CLANG_DIR: $CLANG_DIR"
+echo "FUCHSIA_SHARED_OUT_DIR: $FUCHSIA_SHARED_OUT_DIR"
+echo "OUT_DIR: $OUT_DIR"
+
+# Env vars used by fake-pkg-config.py, cross files, cmake files
+export FUCHSIA_DIR=$FUCHSIA_DIR
+export FUCHSIA_SHARED_OUT_DIR=$FUCHSIA_SHARED_OUT_DIR
+export CLANG_DIR=$CLANG_DIR
+export PKG_CONFIG_PATH=$OUT_DIR/install/lib/pkgconfig
+
+mkdir -p $OUT_DIR
+
+#
+# Build libva with meson
+#
+sed -e "s+SYSROOT_DIR+$SYSROOT_DIR+g" -e "s+CLANG_DIR+$CLANG_DIR+g" -e "s+THIS_DIR+$SCRIPT_DIR+g" $SCRIPT_DIR/meson/x86_64-fuchsia.cross > $OUT_DIR/fuchsia.cross
+meson --prefix=$OUT_DIR/install --cross-file $OUT_DIR/fuchsia.cross \
+  -Ddisable_drm=true\
+  -Dwith_wayland=no\
+  -Dwith_x11=no\
+  -Dwith_glx=no\
+  -Dwith_magma=yes\
+  -Ddriverdir=. \
+  $FUCHSIA_DIR/third_party/intel/libva $OUT_DIR/libva
+ninja -C $OUT_DIR/libva install
+
+#
+# Build gmmlib with cmake
+#
+cmake -GNinja -S $FUCHSIA_DIR/third_party/intel/gmmlib -B $OUT_DIR/gmmlib -Wno-dev \
+  -DBUILD_TYPE="$TARGET"\
+  -DRUN_TEST_SUITE=NO\
+  -DCMAKE_TOOLCHAIN_FILE=$SCRIPT_DIR/cmake/Fuchsia.cmake\
+  -DCMAKE_INSTALL_PREFIX=$OUT_DIR/install\
+  -DFUCHSIA_TOOLCHAIN=$CLANG_DIR\
+  -DFUCHSIA_SYSTEM_PROCESSOR=x86_64\
+  -DFUCHSIA_SYSROOT=$SYSROOT_DIR
+ninja -C $OUT_DIR/gmmlib install
+
+#
+# Build media-driver with cmake
+#
+cmake -GNinja -S $FUCHSIA_DIR/third_party/intel/media-driver -B $OUT_DIR/media-driver -Wno-dev \
+  -DPLATFORM=Fuchsia\
+  -DUSE_MAGMA=YES\
+  -DBUILD_TYPE="$TARGET"\
+  -DBUILD_CMRTLIB=NO\
+  -DENABLE_KERNELS=ON\
+  -DENABLE_NONFREE_KERNELS=OFF\
+  -DCMAKE_TOOLCHAIN_FILE=$SCRIPT_DIR/cmake/Fuchsia.cmake\
+  -DCMAKE_INSTALL_PREFIX=$OUT_DIR/install\
+  -DFUCHSIA_TOOLCHAIN=$CLANG_DIR\
+  -DFUCHSIA_SYSTEM_PROCESSOR=x86_64\
+  -DFUCHSIA_SYSROOT=$SYSROOT_DIR
+ninja -C $OUT_DIR/media-driver install
+
+#
+# Fuchsia build expects stripped libraries
+#
+$CLANG_DIR/bin/llvm-strip $OUT_DIR/install/lib/libva.so.2
+ls -l $OUT_DIR/install/lib/libva.so.2
+$CLANG_DIR/bin/llvm-readelf -needed-libs $OUT_DIR/install/lib/libva.so.2
+
+$CLANG_DIR/bin/llvm-strip $OUT_DIR/install/lib/libva-magma.so.2
+ls -l $OUT_DIR/install/lib/libva-magma.so.2
+$CLANG_DIR/bin/llvm-readelf -needed-libs $OUT_DIR/install/lib/libva-magma.so.2
+
+$CLANG_DIR/bin/llvm-strip $OUT_DIR/install/lib/libigdgmm.so.11
+ls -l $OUT_DIR/install/lib/libigdgmm.so.11
+$CLANG_DIR/bin/llvm-readelf -needed-libs $OUT_DIR/install/lib/libigdgmm.so.11
+
+$CLANG_DIR/bin/llvm-strip $OUT_DIR/install/./iHD_drv_video.so
+ls -l $OUT_DIR/install/./iHD_drv_video.so
+$CLANG_DIR/bin/llvm-readelf -needed-libs $OUT_DIR/install/./iHD_drv_video.so
diff --git a/fuchsia/cmake/Fuchsia.cmake b/fuchsia/cmake/Fuchsia.cmake
new file mode 100644
index 0000000..5777af1
--- /dev/null
+++ b/fuchsia/cmake/Fuchsia.cmake
@@ -0,0 +1,49 @@
+# Copyright 2017 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Need support for CMAKE_C_COMPILER_TARGET
+cmake_minimum_required(VERSION 3.0)
+
+set(CMAKE_SYSTEM_NAME Fuchsia)
+
+set(CMAKE_SYSROOT ${FUCHSIA_SYSROOT})
+
+if(NOT DEFINED FUCHSIA_TOOLCHAIN)
+  string(TOLOWER ${CMAKE_HOST_SYSTEM_PROCESSOR} HOST_SYSTEM_PROCESSOR)
+  if(HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
+    set(HOST_SYSTEM_PROCESSOR "x64")
+  elseif(HOST_SYSTEM_PROCESSOR STREQUAL "aarch64")
+    set(HOST_SYSTEM_PROCESSOR "arm64")
+  endif()
+  string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} HOST_SYSTEM_NAME)
+  if(HOST_SYSTEM_NAME STREQUAL "darwin")
+    set(HOST_SYSTEM_NAME "mac")
+  endif()
+  set(FUCHSIA_TOOLCHAIN "${CMAKE_CURRENT_LIST_DIR}/../prebuilt/third_party/clang/${HOST_SYSTEM_NAME}-${HOST_SYSTEM_PROCESSOR}")
+endif()
+
+if(NOT DEFINED FUCHSIA_COMPILER_TARGET)
+  set(FUCHSIA_COMPILER_TARGET "${FUCHSIA_SYSTEM_PROCESSOR}-fuchsia")
+endif()
+
+set(CMAKE_C_COMPILER "${FUCHSIA_TOOLCHAIN}/bin/clang")
+set(CMAKE_C_COMPILER_TARGET ${FUCHSIA_COMPILER_TARGET} CACHE STRING "")
+set(CMAKE_CXX_COMPILER "${FUCHSIA_TOOLCHAIN}/bin/clang++")
+set(CMAKE_CXX_COMPILER_TARGET ${FUCHSIA_COMPILER_TARGET} CACHE STRING "")
+set(CMAKE_ASM_COMPILER "${FUCHSIA_TOOLCHAIN}/bin/clang")
+set(CMAKE_ASM_COMPILER_TARGET ${FUCHSIA_COMPILER_TARGET} CACHE STRING "")
+
+set(CMAKE_LINKER "${FUCHSIA_TOOLCHAIN}/bin/ld.lld" CACHE PATH "")
+set(CMAKE_AR "${FUCHSIA_TOOLCHAIN}/bin/llvm-ar" CACHE PATH "")
+set(CMAKE_RANLIB "${FUCHSIA_TOOLCHAIN}/bin/llvm-ranlib" CACHE PATH "")
+set(CMAKE_NM "${FUCHSIA_TOOLCHAIN}/bin/llvm-nm" CACHE PATH "")
+set(CMAKE_OBJCOPY "${FUCHSIA_TOOLCHAIN}/bin/llvm-objcopy" CACHE PATH "")
+set(CMAKE_OBJDUMP "${FUCHSIA_TOOLCHAIN}/bin/llvm-objdump" CACHE PATH "")
+set(CMAKE_STRIP "${FUCHSIA_TOOLCHAIN}/bin/llvm-strip" CACHE PATH "")
+
+set(CMAKE_FIND_ROOT_PATH ${FUCHSIA_SYSROOT})
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
diff --git a/fuchsia/meson/fake-pkg-config.py b/fuchsia/meson/fake-pkg-config.py
new file mode 100755
index 0000000..a7dd91e
--- /dev/null
+++ b/fuchsia/meson/fake-pkg-config.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python3
+
+# This script invoked as pkg-config supporting Fuchsia cross compilation for packages built with
+# meson (such as libva - see build.sh).
+
+import getopt
+import os
+import subprocess
+import sys
+
+if __name__ == '__main__':
+    optlist, args = getopt.gnu_getopt(
+        sys.argv[1:], '', ['version', 'modversion', 'cflags', 'libs'])
+
+    if optlist[0][0] == "--version":
+        print("0.1")
+        exit(0)
+
+    fuchsia_dir = os.getenv("FUCHSIA_DIR", "<no-fuchsia-shared-out-dir>")
+    fuchsia_shared_out_dir = os.getenv(
+        "FUCHSIA_SHARED_OUT_DIR", "<no-fuchsia-shared-out-dir>")
+
+    for lib in args:
+        if lib == "magma":
+            if optlist[0][0] == "--modversion":
+                print("1.0.0")
+            elif optlist[0][0] == "--cflags":
+                print(
+                    f"-I{fuchsia_dir}/src/graphics/lib/magma/include/magma_abi "
+                )
+            elif optlist[0][0] == "--libs":
+                print(
+                    f"{fuchsia_shared_out_dir}/obj/src/graphics/lib/magma/src/libmagma/libmagma_complete.a "
+                )
+            else:
+                print("Unrecognized option")
+                exit(1)
+
+        else:
+            sys.stderr.write("Unrecognized library: %s" % lib)
+            exit(2)
+
+    exit(0)
diff --git a/fuchsia/meson/x86_64-fuchsia-clang b/fuchsia/meson/x86_64-fuchsia-clang
new file mode 100755
index 0000000..ef19505
--- /dev/null
+++ b/fuchsia/meson/x86_64-fuchsia-clang
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+$CLANG_DIR/bin/clang --target=x86_64-unknown-fuchsia "$@"
\ No newline at end of file
diff --git a/fuchsia/meson/x86_64-fuchsia-clang++ b/fuchsia/meson/x86_64-fuchsia-clang++
new file mode 100755
index 0000000..d00330a
--- /dev/null
+++ b/fuchsia/meson/x86_64-fuchsia-clang++
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+$CLANG_DIR/bin/clang++ --target=x86_64-unknown-fuchsia "$@"
\ No newline at end of file
diff --git a/fuchsia/meson/x86_64-fuchsia.cross b/fuchsia/meson/x86_64-fuchsia.cross
new file mode 100644
index 0000000..a900c4c
--- /dev/null
+++ b/fuchsia/meson/x86_64-fuchsia.cross
@@ -0,0 +1,21 @@
+[binaries]
+c = 'THIS_DIR/meson/x86_64-fuchsia-clang'
+cpp = 'THIS_DIR/meson/x86_64-fuchsia-clang++'
+ar = 'CLANG_DIR/bin/llvm-ar'
+strip = 'CLANG_DIR/bin/strip'
+pkgconfig = 'THIS_DIR/meson/fake-pkg-config.py'
+
+[host_machine]
+system = 'linux'
+cpu_family = 'x86_64'
+cpu = 'x86_64'
+endian = 'little'
+
+[properties]
+has_function_timespec_get = true
+
+[built-in options]
+c_args = ['--sysroot', 'SYSROOT_DIR']
+cpp_args = ['--sysroot', 'SYSROOT_DIR', '-std=c++17']
+c_link_args = ['--sysroot', 'SYSROOT_DIR']
+cpp_link_args = ['--sysroot', 'SYSROOT_DIR']
diff --git a/fuchsia/test/BUILD.gn b/fuchsia/test/BUILD.gn
new file mode 100644
index 0000000..f941b99
--- /dev/null
+++ b/fuchsia/test/BUILD.gn
@@ -0,0 +1,27 @@
+# Copyright 2021 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+
+import("//build/components.gni")
+
+executable("va-test-bin") {
+  testonly = true
+  sources = [ "va-test.cc" ]
+  deps = [
+    "//src/graphics/lib/magma/src/libmagma",
+    "//src/lib/fxl/test:gtest_main",
+    "//third_party/googletest:gtest",
+    "//third_party/intel/media-driver/fuchsia:va-intel",
+    "//zircon/system/ulib/zx",
+  ]
+}
+
+fuchsia_test_component("va-test-component") {
+  deps = [ ":va-test-bin" ]
+  manifest = "meta/va-test.cmx"
+}
+
+fuchsia_test_package("va-test") {
+  test_components = [ ":va-test-component" ]
+}
diff --git a/fuchsia/test/meta/va-test.cmx b/fuchsia/test/meta/va-test.cmx
new file mode 100644
index 0000000..c8f57a0
--- /dev/null
+++ b/fuchsia/test/meta/va-test.cmx
@@ -0,0 +1,13 @@
+{
+    "include": [
+        "syslog/client.shard.cmx"
+    ],
+    "program": {
+        "binary": "bin/va-test-bin"
+    },
+    "sandbox": {
+        "dev": [
+            "class/gpu"
+        ]
+    }
+}
diff --git a/fuchsia/test/va-test.cc b/fuchsia/test/va-test.cc
new file mode 100644
index 0000000..2b91e27
--- /dev/null
+++ b/fuchsia/test/va-test.cc
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2021 The Fuchsia Authors. All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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 <lib/fdio/directory.h>
+#include <lib/zx/channel.h>
+#include <stdio.h>
+
+#include <filesystem>
+
+#include <gtest/gtest.h>
+#include <va/va_magma.h>
+
+class VaTest : public testing::Test {
+ public:
+  VaTest(uint64_t vendor_id) : vendor_id_(vendor_id) {}
+
+  void SetUp() override {
+    for (auto& p : std::filesystem::directory_iterator("/dev/class/gpu")) {
+      {
+        zx::channel local, remote;
+        ASSERT_EQ(ZX_OK, zx::channel::create(0 /*flags*/, &local, &remote));
+        ASSERT_EQ(ZX_OK, fdio_service_connect(p.path().c_str(), remote.release()));
+        ASSERT_EQ(MAGMA_STATUS_OK, magma_device_import(local.release(), &device_));
+      }
+
+      {
+        uint64_t vendor_id;
+        magma_status_t magma_status = magma_query2(device_, MAGMA_QUERY_VENDOR_ID, &vendor_id);
+        if (magma_status == MAGMA_STATUS_OK && vendor_id == vendor_id_) {
+          break;
+        }
+      }
+
+      magma_device_release(device_);
+      device_ = {};
+    }
+
+    ASSERT_TRUE(device_);
+  }
+
+  void TearDown() override {
+    if (device_)
+      magma_device_release(device_);
+  }
+
+  uint64_t vendor_id_;
+  magma_device_t device_{};
+};
+
+class IntelVaTest : public VaTest {
+ public:
+  IntelVaTest() : VaTest(0x8086) {}
+};
+
+TEST_F(IntelVaTest, Open) {
+  VADisplay display = vaGetDisplayMagma(device_);
+  ASSERT_TRUE(display);
+  int major_ver, minor_ver;
+  EXPECT_EQ(VA_STATUS_SUCCESS, vaInitialize(display, &major_ver, &minor_ver));
+  EXPECT_EQ(VA_STATUS_SUCCESS, vaTerminate(display));
+}
diff --git a/media_driver/cmake/linux/media_compile_flags_linux.cmake b/media_driver/cmake/linux/media_compile_flags_linux.cmake
index 681975b..c5c42ca 100755
--- a/media_driver/cmake/linux/media_compile_flags_linux.cmake
+++ b/media_driver/cmake/linux/media_compile_flags_linux.cmake
@@ -82,7 +82,7 @@
     )
 endif()
 
-if(NOT ${PLATFORM} STREQUAL "android")
+if(NOT ${PLATFORM} STREQUAL "android" AND NOT ${PLATFORM} STREQUAL "Fuchsia")
     set(MEDIA_COMPILER_FLAGS_COMMON
         ${MEDIA_COMPILER_FLAGS_COMMON}
         -D__linux__
@@ -92,6 +92,26 @@
         )
     endif()
 
+if(USE_MAGMA)
+    set(MEDIA_COMPILER_FLAGS_COMMON
+        ${MEDIA_COMPILER_FLAGS_COMMON}
+        -DUSE_MAGMA=1
+    )
+    include_directories(
+        "$ENV{FUCHSIA_DIR}/src/graphics/lib/magma/include/magma_abi"
+        "$ENV{FUCHSIA_DIR}/src/graphics/drivers/msd-intel-gen/include"
+    )
+    link_libraries(
+        "$ENV{FUCHSIA_SHARED_OUT_DIR}/obj/src/graphics/lib/magma/src/libmagma/libmagma_complete.a"
+    )
+endif()
+
+if(${PLATFORM} STREQUAL "Fuchsia")
+    link_libraries(
+        "zircon"
+    )
+endif()
+
 set(MEDIA_COMPILER_CXX_FLAGS_COMMON
     # for cpp
     -Wreorder
@@ -106,7 +126,14 @@
     -fcheck-new
 )
 
-if(NOT ${PLATFORM} STREQUAL "android")
+if (${PLATFORM} STREQUAL "Fuchsia")
+    set(MEDIA_COMPILER_CXX_FLAGS_COMMON
+        ${MEDIA_COMPILER_CXX_FLAGS_COMMON}
+        -fexperimental-relative-c++-abi-vtables
+    )
+endif()
+
+if(NOT ${PLATFORM} STREQUAL "android" AND NOT ${PLATFORM} STREQUAL "Fuchsia")
     set(MEDIA_COMPILER_CXX_FLAGS_COMMON
         ${MEDIA_COMPILER_CXX_FLAGS_COMMON}
         -std=c++1y
@@ -186,7 +213,7 @@
 
 include(${MEDIA_EXT_CMAKE}/ext/linux/media_compile_flags_linux_ext.cmake OPTIONAL)
 
-if(${PLATFORM} STREQUAL "linux")
+if(${PLATFORM} STREQUAL "linux" OR ${PLATFORM} STREQUAL "Fuchsia")
     #set predefined compiler flags set
     add_compile_options("${MEDIA_COMPILER_FLAGS_COMMON}")
     add_compile_options("$<$<CONFIG:Debug>:${MEDIA_COMPILER_FLAGS_DEBUG}>")
diff --git a/media_driver/cmake/media_compile_flags.cmake b/media_driver/cmake/media_compile_flags.cmake
index 9b2d622..bb706a5 100644
--- a/media_driver/cmake/media_compile_flags.cmake
+++ b/media_driver/cmake/media_compile_flags.cmake
@@ -18,7 +18,7 @@
 # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 # OTHER DEALINGS IN THE SOFTWARE.
 
-if(${PLATFORM} STREQUAL "linux")
+if(${PLATFORM} STREQUAL "linux" OR ${PLATFORM} STREQUAL "Fuchsia")
     include(${MEDIA_DRIVER_CMAKE}/linux/media_compile_flags_linux.cmake)
 else()
     include(${MEDIA_EXT_CMAKE}/ext/media_compile_flags_ext.cmake OPTIONAL)
diff --git a/media_driver/cmake/media_feature_flags.cmake b/media_driver/cmake/media_feature_flags.cmake
index e524a7c..434b7e8 100644
--- a/media_driver/cmake/media_feature_flags.cmake
+++ b/media_driver/cmake/media_feature_flags.cmake
@@ -19,7 +19,7 @@
 # OTHER DEALINGS IN THE SOFTWARE.
 
 
-if(${PLATFORM} STREQUAL "linux")
+if(${PLATFORM} STREQUAL "linux" OR ${PLATFORM} STREQUAL "Fuchsia")
     include(${MEDIA_DRIVER_CMAKE}/linux/media_feature_flags_linux.cmake)
 else()
     include(${MEDIA_EXT_CMAKE}/ext/media_feature_flags_ext.cmake OPTIONAL)
diff --git a/media_driver/cmake/media_gen_flags.cmake b/media_driver/cmake/media_gen_flags.cmake
index ab66df1..32d5010 100644
--- a/media_driver/cmake/media_gen_flags.cmake
+++ b/media_driver/cmake/media_gen_flags.cmake
@@ -18,7 +18,7 @@
 # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 # OTHER DEALINGS IN THE SOFTWARE.
 
-if(${PLATFORM} STREQUAL "linux")
+if(${PLATFORM} STREQUAL "linux" OR ${PLATFORM} STREQUAL "Fuchsia")
     include(${MEDIA_DRIVER_CMAKE}/linux/media_gen_flags_linux.cmake)
 else()
     include(${MEDIA_EXT_CMAKE}/ext/media_gen_flags_ext.cmake OPTIONAL)
diff --git a/media_driver/cmake/media_include_paths.cmake b/media_driver/cmake/media_include_paths.cmake
index 64c1019..4c15039 100644
--- a/media_driver/cmake/media_include_paths.cmake
+++ b/media_driver/cmake/media_include_paths.cmake
@@ -30,7 +30,7 @@
 include_directories(${BS_DIR_GMMLIB}/inc)
 include_directories(${BS_DIR_SOURCE}/huc/inc)
 
-if(${PLATFORM} STREQUAL "linux")
+if(${PLATFORM} STREQUAL "linux" OR ${PLATFORM} STREQUAL "Fuchsia")
     include(${MEDIA_DRIVER_CMAKE}/linux/media_include_paths_linux.cmake)
 else()
     include(${MEDIA_EXT_CMAKE}/ext/media_include_paths_ext.cmake OPTIONAL)
diff --git a/media_driver/cmake/media_utils.cmake b/media_driver/cmake/media_utils.cmake
index 44b084b..9d26814 100644
--- a/media_driver/cmake/media_utils.cmake
+++ b/media_driver/cmake/media_utils.cmake
@@ -31,7 +31,7 @@
 
 # add current path to include path
 macro(media_add_curr_to_include_path)
-    if(${PLATFORM} STREQUAL "linux")
+    if(${PLATFORM} STREQUAL "linux" OR ${PLATFORM} STREQUAL "Fuchsia")
         include_directories(${CMAKE_CURRENT_LIST_DIR})
     else()
         media_add_curr_to_include_path_ext(${CMAKE_CURRENT_LIST_DIR})
diff --git a/media_driver/linux/common/cm/hal/cm_hal_os.cpp b/media_driver/linux/common/cm/hal/cm_hal_os.cpp
index 47d3b68..a296d9e 100644
--- a/media_driver/linux/common/cm/hal/cm_hal_os.cpp
+++ b/media_driver/linux/common/cm/hal/cm_hal_os.cpp
@@ -1123,7 +1123,7 @@
 MOS_STATUS HalCm_EnableTurboBoost_Linux(
     PCM_HAL_STATE             state)
 {
-#ifndef ANDROID
+#if !defined(ANDROID) && !defined(__Fuchsia__)
     struct drm_i915_gem_context_param ctxParam;
     int32_t retVal = 0;
 
@@ -1132,6 +1132,9 @@
     ctxParam.value = 1;
     retVal = drmIoctl( state->osInterface->pOsContext->fd,
                       DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &ctxParam );
+#else
+    //TODO(fxbug.dev/78281) - remove
+    fprintf(stderr, "HalCm_EnableTurboBoost_Linux: not implemented\n");
 #endif
     //if drmIoctl fail, we will stay in normal mode.
     return MOS_STATUS_SUCCESS;
diff --git a/media_driver/linux/common/cm/hal/cm_innerdef_os.h b/media_driver/linux/common/cm/hal/cm_innerdef_os.h
index eef1c99..7906cb0 100644
--- a/media_driver/linux/common/cm/hal/cm_innerdef_os.h
+++ b/media_driver/linux/common/cm/hal/cm_innerdef_os.h
@@ -36,7 +36,9 @@
 #include "mos_os.h"
 #include "media_libva_common.h"
 #include <sys/types.h>
+#if defined(__linux__)
 #include <sys/syscall.h>
+#endif
 #include <unistd.h>
 
 //Require DRM VMAP patch,
@@ -94,6 +96,10 @@
 
 #endif
 
+#if defined(__Fuchsia__) // TODO(fxbug.dev/78281)
+#define CmGetCurProcessId() 0
+#define CmGetCurThreadId()  0
+#else
 #define CmGetCurProcessId() getpid()
 #define CmGetCurThreadId()  syscall(SYS_gettid)
-
+#endif
diff --git a/media_driver/linux/common/codec/ddi/media_libva_decoder.cpp b/media_driver/linux/common/codec/ddi/media_libva_decoder.cpp
index 3149b20..f6d18b8 100644
--- a/media_driver/linux/common/codec/ddi/media_libva_decoder.cpp
+++ b/media_driver/linux/common/codec/ddi/media_libva_decoder.cpp
@@ -47,11 +47,14 @@
 #include <X11/Xutil.h>
 #endif
 
+#if defined(__linux__)
 #include <linux/fb.h>
+#endif
 
 typedef MediaDdiFactory<DdiMediaDecode, DDI_DECODE_CONFIG_ATTR> DdiDecodeFactory;
 static int32_t DdiDecode_GetDisplayInfo(VADriverContextP ctx)
 {
+#if defined(__linux__)
     PDDI_MEDIA_CONTEXT mediaDrvCtx        = DdiMedia_GetMediaContext(ctx);
     int32_t fd                            = -1;
     struct fb_var_screeninfo              vsinfo;
@@ -84,6 +87,11 @@
     DDI_NORMALMESSAGE("DDI:mediaDrvCtx->uiDisplayHeight =%d",mediaDrvCtx->uiDisplayHeight);
 
     return 0;
+#else
+    // TODO(fxbug.dev/78281) remove
+    fprintf(stderr, "DdiDecode_GetDisplayInfo not implemented\n");
+    return -1;
+#endif
 }
 
 VAStatus DdiDecode_CreateBuffer(
diff --git a/media_driver/linux/common/ddi/media_libva.cpp b/media_driver/linux/common/ddi/media_libva.cpp
index 1cdc576..cd41745 100755
--- a/media_driver/linux/common/ddi/media_libva.cpp
+++ b/media_driver/linux/common/ddi/media_libva.cpp
@@ -36,7 +36,11 @@
 #include <X11/Xutil.h>
 #endif
 
+#if defined(USE_MAGMA)
+#include "magma_fd.h"
+#else
 #include <linux/fb.h>
+#endif
 
 #include "media_libva.h"
 
@@ -1568,6 +1572,9 @@
 
     DDI_CHK_NULL(ctx,          "nullptr ctx",       VA_STATUS_ERROR_INVALID_CONTEXT);
 
+#if defined(USE_MAGMA)
+    int32_t devicefd = get_magma_fd_for_device(ctx->magma_device);
+#else
     struct drm_state *pDRMState = (struct drm_state *)ctx->drm_state;
     DDI_CHK_NULL(pDRMState,    "nullptr pDRMState", VA_STATUS_ERROR_INVALID_CONTEXT);
 
@@ -1582,6 +1589,7 @@
         }
     }
     int32_t devicefd = pDRMState->fd;
+#endif
 
     if(major_version)
     {
diff --git a/media_driver/linux/common/ddi/media_libva_common.h b/media_driver/linux/common/ddi/media_libva_common.h
index acdd9c6..8e9f13a 100644
--- a/media_driver/linux/common/ddi/media_libva_common.h
+++ b/media_driver/linux/common/ddi/media_libva_common.h
@@ -30,7 +30,9 @@
 
 #include <pthread.h>
 
+#if !defined(USE_MAGMA)
 #include "xf86drm.h"
+#endif
 #include "drm.h"
 #include "i915_drm.h"
 #include "mos_bufmgr.h"
diff --git a/media_driver/linux/common/os/hwinfo_linux.c b/media_driver/linux/common/os/hwinfo_linux.c
index d653596..52f82bd 100644
--- a/media_driver/linux/common/os/hwinfo_linux.c
+++ b/media_driver/linux/common/os/hwinfo_linux.c
@@ -32,6 +32,9 @@
 #include "linux_shadow_skuwa.h"
 #include "mos_solo_generic.h"
 
+#if defined(USE_MAGMA)
+#include "magma_fd.h"
+#endif
 
 typedef DeviceInfoFactory<struct GfxDeviceInfo> DeviceInfoFact;
 typedef DeviceInfoFactory<struct LinuxDeviceInit> DeviceInitFact;
@@ -56,7 +59,11 @@
 
     gp.param = param;
     gp.value = (int32_t *)retValue;
+#if defined(USE_MAGMA)
+    return query_magma_fd(fd, param, retValue);
+#else
     return drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp) == 0;
+#endif
 }
 
 /*****************************************************************************\
diff --git a/media_driver/linux/common/os/i915/include/uapi/drm.h b/media_driver/linux/common/os/i915/include/uapi/drm.h
index 438abde..1c6364e 100644
--- a/media_driver/linux/common/os/i915/include/uapi/drm.h
+++ b/media_driver/linux/common/os/i915/include/uapi/drm.h
@@ -42,6 +42,20 @@
 #include <asm/ioctl.h>
 typedef unsigned int drm_handle_t;
 
+#elif defined(__Fuchsia__)
+
+#include <sys/types.h>
+typedef int8_t __s8;
+typedef uint8_t __u8;
+typedef int16_t __s16;
+typedef uint16_t __u16;
+typedef int32_t __s32;
+typedef uint32_t __u32;
+typedef int64_t __s64;
+typedef uint64_t __u64;
+typedef size_t __kernel_size_t;
+typedef unsigned long drm_handle_t;
+
 #else /* One of the BSDs */
 
 #include <stdint.h>
diff --git a/media_driver/linux/common/os/i915/mos_bufmgr_api.c b/media_driver/linux/common/os/i915/mos_bufmgr_api.c
index f451506..70fdd0a 100644
--- a/media_driver/linux/common/os/i915/mos_bufmgr_api.c
+++ b/media_driver/linux/common/os/i915/mos_bufmgr_api.c
@@ -39,7 +39,9 @@
 #include "libdrm_macros.h"
 #include "mos_bufmgr.h"
 #include "mos_bufmgr_priv.h"
+#if !defined(USE_MAGMA)
 #include "xf86drm.h"
+#endif
 
 /** @file mos_bufmgr_api.c
  *
diff --git a/media_driver/linux/common/os/magma/media_srcs.cmake b/media_driver/linux/common/os/magma/media_srcs.cmake
new file mode 100644
index 0000000..40b197f
--- /dev/null
+++ b/media_driver/linux/common/os/magma/media_srcs.cmake
@@ -0,0 +1,31 @@
+# Copyright (c) 2021, The Fuchsia Authors
+#
+# 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 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.
+
+media_include_subdirectory(include)
+
+set(TMP_SOURCES_
+    ${CMAKE_CURRENT_LIST_DIR}/mos_bufmgr_stub.c
+    ${CMAKE_CURRENT_LIST_DIR}/../i915/mos_bufmgr_api.c
+)
+
+set(SOURCES_
+    ${SOURCES_}
+    ${TMP_SOURCES_}
+)
diff --git a/media_driver/linux/common/os/magma/mos_bufmgr_stub.c b/media_driver/linux/common/os/magma/mos_bufmgr_stub.c
new file mode 100644
index 0000000..5e5591d
--- /dev/null
+++ b/media_driver/linux/common/os/magma/mos_bufmgr_stub.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright © 2021 The Fuchsia Authors
+ *
+ * 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 "mos_bufmgr.h"
+#include "mos_bufmgr_priv.h"
+#include <assert.h>
+#include <stdio.h>
+
+#define LOG_VERBOSE(msg, ...) do { \
+    if (true) \
+        fprintf(stderr, "%s:%d " msg "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
+        fflush(stderr); \
+} while (0)
+
+int mos_gem_bo_wait(struct mos_linux_bo *bo, int64_t timeout_ns)
+{
+    LOG_VERBOSE("mos_gem_bo_wait unimplemented");
+    return 0;
+}
+
+void mos_gem_bo_clear_relocs(struct mos_linux_bo *bo, int start)
+{
+    LOG_VERBOSE("mos_gem_bo_clear_relocs unimplemented");
+}
+
+struct mos_bufmgr* mos_bufmgr_gem_init(int fd, int batch_size)
+{
+    LOG_VERBOSE("mos_bufmgr_gem_init unimplemented");
+    return NULL;
+}
+
+void mos_bufmgr_gem_enable_reuse(struct mos_bufmgr *bufmgr)
+{
+    LOG_VERBOSE("mos_bufmgr_gem_enable_reuse unimplemented");
+}
+
+int mos_bufmgr_gem_get_devid(struct mos_bufmgr *bufmgr)
+{
+    LOG_VERBOSE("mos_bufmgr_gem_get_devid unimplemented");
+    return 0;
+}
+
+int mos_bo_gem_export_to_prime(struct mos_linux_bo *bo, int *prime_fd)
+{
+    LOG_VERBOSE("mos_bo_gem_export_to_prime unimplemented");
+    return 0;
+}
+
+struct mos_linux_bo * mos_bo_gem_create_from_name(struct mos_bufmgr *bufmgr,
+                  const char *name,
+                  unsigned int handle)
+{
+    LOG_VERBOSE("mos_bo_gem_create_from_name unimplemented");
+    return NULL;
+}
+
+void mos_gem_context_destroy(struct mos_linux_context *ctx)
+{
+    LOG_VERBOSE("mos_gem_context_destroy unimplemented");
+}
+
+int mos_gem_bo_map_wc(struct mos_linux_bo *bo) {
+    LOG_VERBOSE("mos_gem_bo_map_wc unimplemented");
+    return 0;
+}
+
+struct mos_linux_bo *mos_bo_gem_create_from_prime(struct mos_bufmgr *bufmgr, int prime_fd, int size)
+{
+    LOG_VERBOSE("mos_bo_gem_create_from_prime unimplemented");
+    return 0;
+}
+
+int mos_gem_bo_map_gtt(struct mos_linux_bo *bo)
+{
+    LOG_VERBOSE("mos_gem_bo_map_gtt unimplemented");
+    return 0;
+}
+
+int mos_gem_bo_map_unsynchronized(struct mos_linux_bo *bo)
+{
+    LOG_VERBOSE("mos_gem_bo_map_unsynchronized unimplemented");
+    return 0;
+}
+
+void mos_gem_bo_start_gtt_access(struct mos_linux_bo *bo, int write_enable)
+{
+    LOG_VERBOSE("mos_gem_bo_start_gtt_access unimplemented");
+}
+
+int mos_gem_bo_unmap_gtt(struct mos_linux_bo *bo)
+{
+    LOG_VERBOSE("mos_gem_bo_unmap_gtt unimplemented");
+    return 0;
+}
+
+int mos_query_device_blob(int fd, MEDIA_SYSTEM_INFO* gfx_info)
+{
+    LOG_VERBOSE("mos_query_device_blob unimplemented");
+    return -1;
+}
+
+int mos_query_engines_count(struct mos_bufmgr *bufmgr,
+                      unsigned int *nengine)
+
+{
+    LOG_VERBOSE("mos_query_engines_count unimplemented");
+    return 0;
+}
+
+int mos_query_engines(struct mos_bufmgr *bufmgr,
+                      __u16 engine_class,
+                      __u64 caps,
+                      unsigned int *nengine,
+                      struct i915_engine_class_instance *ci)
+{
+    LOG_VERBOSE("mos_query_engines unimplemented");
+    return 0;
+}
+
+int mos_get_context_param(struct mos_linux_context *ctx,
+                uint32_t size,
+                uint64_t param,
+                uint64_t *value)
+{
+    LOG_VERBOSE("mos_get_context_param unimplemented");
+    return 0;
+}
+
+int mos_set_context_param(struct mos_linux_context *ctx,
+                uint32_t size,
+                uint64_t param,
+                uint64_t value)
+{
+    LOG_VERBOSE("mos_set_context_param unimplemented");
+    return 0;
+}
+
+struct mos_linux_context * mos_gem_context_create(struct mos_bufmgr *bufmgr)
+{
+    LOG_VERBOSE("mos_gem_context_create_ext unimplemented");
+    return NULL;
+}
+
+struct mos_linux_context *mos_gem_context_create_ext(struct mos_bufmgr *bufmgr, __u32 flags)
+{
+    LOG_VERBOSE("mos_gem_context_create_ext unimplemented");
+    return NULL;
+}
+
+struct drm_i915_gem_vm_control* mos_gem_vm_create(struct mos_bufmgr *bufmgr)
+{
+    LOG_VERBOSE("mos_gem_vm_create unimplemented");
+    return NULL;
+}
+
+struct mos_linux_context *
+mos_gem_context_create_shared(struct mos_bufmgr *bufmgr, mos_linux_context* ctx, __u32 flags)
+{
+    LOG_VERBOSE("mos_gem_context_create_shared unimplemented");
+    return NULL;
+}
+
+int
+mos_get_reset_stats(struct mos_linux_context *ctx,
+              uint32_t *reset_count,
+              uint32_t *active,
+              uint32_t *pending)
+{
+    LOG_VERBOSE("mos_get_reset_stats unimplemented");
+    return 0;
+}
+
+void mos_gem_vm_destroy(struct mos_bufmgr *bufmgr, struct drm_i915_gem_vm_control* vm)
+{
+    LOG_VERBOSE("mos_gem_vm_destroy unimplemented");
+}
+
+int mos_gem_bo_unmap_wc(struct mos_linux_bo *bo)
+{
+    LOG_VERBOSE("mos_gem_bo_unmap_wc unimplemented");
+    return 0;
+}
+
+bool mos_gem_bo_is_softpin(struct mos_linux_bo *bo)
+{
+    LOG_VERBOSE("mos_gem_bo_is_softpin unimplemented");
+    return false;
+}
+
+int mos_gem_bo_context_exec2(struct mos_linux_bo *bo, int used, struct mos_linux_context *ctx,
+                           drm_clip_rect_t *cliprects, int num_cliprects, int DR4,
+                           unsigned int flags, int *fence) {
+    LOG_VERBOSE("mos_gem_bo_context_exec2 unimplemented");
+    return 0;
+}
+
+int mos_get_context_param_sseu(struct mos_linux_context *ctx,
+                struct drm_i915_gem_context_param_sseu *sseu) {
+    LOG_VERBOSE("mos_get_context_param_sseu unimplemented");
+    return 0;
+}
+
+unsigned int mos_hweight8(uint8_t w)
+{
+    LOG_VERBOSE("mos_hweight8 unimplemented");
+    return 0;
+}
+
+uint8_t mos_switch_off_n_bits(uint8_t in_mask, int n)
+{
+    LOG_VERBOSE("mos_switch_off_n_bits unimplemented");
+    return 0;
+}
+
+int mos_set_context_param_sseu(struct mos_linux_context *ctx,
+                struct drm_i915_gem_context_param_sseu sseu) {
+    LOG_VERBOSE("mos_set_context_param_sseu unimplemented");
+    return 0;
+}
+
+int mos_set_context_param_load_balance(struct mos_linux_context *ctx,
+                     struct i915_engine_class_instance *ci,
+                     unsigned int count)
+{
+    LOG_VERBOSE("mos_set_context_param_load_balance unimplemented");
+    return 0;
+}
+
+int mos_set_context_param_bond(struct mos_linux_context *ctx,
+                        struct i915_engine_class_instance master_ci,
+                        struct i915_engine_class_instance *bond_ci,
+                        unsigned int bond_count)
+{
+    LOG_VERBOSE("mos_set_context_param_bond unimplemented");
+    return 0;
+}
+
+int mos_set_context_param_parallel(struct mos_linux_context *ctx,
+                     struct i915_engine_class_instance *ci,
+                     unsigned int count)
+{
+    LOG_VERBOSE("mos_set_context_param_parallel unimplemented");
+    return 0;
+}
+
+bool mos_gem_bo_is_exec_object_async(struct mos_linux_bo *bo)
+{
+    LOG_VERBOSE("mos_gem_bo_is_exec_object_async unimplemented");
+    return 0;
+}
+
+int mos_gem_bo_context_exec3(struct mos_linux_bo **bo, int num_bo, struct mos_linux_context *ctx,
+                               struct drm_clip_rect *cliprects, int num_cliprects, int DR4,
+                               unsigned int flags, int *fence)
+{
+    LOG_VERBOSE("mos_gem_bo_context_exec3 unimplemented");
+    return 0;
+}
diff --git a/media_driver/linux/common/os/magma_fd.cpp b/media_driver/linux/common/os/magma_fd.cpp
new file mode 100644
index 0000000..296cb82
--- /dev/null
+++ b/media_driver/linux/common/os/magma_fd.cpp
@@ -0,0 +1,114 @@
+/*
+* Copyright (c) 2021, The Fuchsia Authors
+*
+* 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 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 "magma_fd.h"
+
+#include <i915_drm.h>
+#include <magma.h>
+#include <magma_intel_gen_defs.h>
+
+#include <assert.h>
+#include <map>
+#include <mutex>
+
+namespace {
+
+struct FakeFdMap {
+  std::map<int32_t, uintptr_t> map;
+  std::mutex mutex;
+  int32_t next_fd = -1;
+};
+
+FakeFdMap* gMap; // never destroyed
+std::once_flag gOnceFlag;
+
+} // namespace
+
+int get_magma_fd_for_device(uintptr_t device) {
+  std::call_once(gOnceFlag, []() { gMap = new FakeFdMap; });
+
+  std::lock_guard<std::mutex> lock(gMap->mutex);
+
+  if (gMap->next_fd < 0)
+    gMap->next_fd = 1;
+
+  int fd = gMap->next_fd++;
+
+  // Roll over fails because we never release fds
+  assert(gMap->map.find(fd) == gMap->map.end());
+
+  gMap->map[fd] = device;
+  return fd;
+}
+
+uintptr_t get_device_for_magma_fd(int fd) {
+  assert(gMap);
+  std::lock_guard<std::mutex> lock(gMap->mutex);
+
+  auto iter = gMap->map.find(fd);
+  if (iter == gMap->map.end())
+    return 0;
+
+  uintptr_t device = iter->second;
+  return device;
+}
+
+bool query_magma_fd(int fd, int32_t param, uint32_t* value_out) {
+  magma_device_t device = get_device_for_magma_fd(fd);
+  if (!device)
+    return false;
+
+  magma_status_t status;
+  uint64_t val64;
+
+  switch (param) {
+    case I915_PARAM_HAS_BSD: // 1st video command streamer instance
+    case I915_PARAM_HAS_VEBOX:
+    case I915_PARAM_HAS_ALIASING_PPGTT:
+      *value_out = 1;
+      return true;
+
+    case I915_PARAM_HAS_BSD2: // 2nd video command streamer instance
+    case 42: //I915_PARAM_HAS_HUC
+    case I915_PARAM_REVISION:
+      *value_out = 0;
+      return true;
+
+    case I915_PARAM_CHIPSET_ID:
+      status = magma_query2(device, MAGMA_QUERY_DEVICE_ID, &val64);
+      if (status != MAGMA_STATUS_OK)
+        return false;
+      *value_out = static_cast<uint32_t>(val64);
+      return true;
+
+    case I915_PARAM_EU_TOTAL:
+    case I915_PARAM_SUBSLICE_TOTAL:
+      status = magma_query2(device, kMsdIntelGenQuerySubsliceAndEuTotal, &val64);
+      if (status != MAGMA_STATUS_OK)
+        return false;
+      *value_out = (param == I915_PARAM_EU_TOTAL) ? static_cast<uint32_t>(val64) : val64 >> 32;
+      return true;
+
+    default:
+      return false;
+  }
+}
diff --git a/media_driver/linux/common/os/magma_fd.h b/media_driver/linux/common/os/magma_fd.h
new file mode 100644
index 0000000..39a7d90
--- /dev/null
+++ b/media_driver/linux/common/os/magma_fd.h
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2021, The Fuchsia Authors
+*
+* 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 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.
+*/
+
+#ifndef MAGMA_FD_H
+#define MAGMA_FD_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Fuchsia devices are 64bit handles, but this project only passes around 32bits
+// because that's sufficient for file descriptors on Linux.
+// Instead of changing the handle type everywhere, just map the Fuchsia device to
+// a fake FD which can only be used with this API.
+int get_magma_fd_for_device(uintptr_t device);
+
+// Performs a query on the device associated with the given FD.
+bool query_magma_fd(int fd, int32_t param, uint32_t* value_out);
+
+// Returns the device associated with the FD, without transferring ownership.
+uintptr_t get_device_for_magma_fd(int fd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/media_driver/linux/common/os/media_srcs.cmake b/media_driver/linux/common/os/media_srcs.cmake
index ee1b1a6..0e69dd3 100644
--- a/media_driver/linux/common/os/media_srcs.cmake
+++ b/media_driver/linux/common/os/media_srcs.cmake
@@ -18,9 +18,14 @@
 # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 # OTHER DEALINGS IN THE SOFTWARE.
 
-media_include_subdirectory(i915)
-if(ENABLE_PRODUCTION_KMD)
-media_include_subdirectory(i915_production)
+if(${PLATFORM} STREQUAL "linux")
+    media_include_subdirectory(i915)
+    if(ENABLE_PRODUCTION_KMD)
+    media_include_subdirectory(i915_production)
+    endif()
+elseif(${PLATFORM} STREQUAL "Fuchsia")
+    media_include_subdirectory(magma)
+    media_include_subdirectory(i915/include)
 endif()
 
 set(TMP_SOURCES_
@@ -40,6 +45,13 @@
     ${CMAKE_CURRENT_LIST_DIR}/mos_os_mock_adaptor_specific.cpp
 )
 
+if (USE_MAGMA)
+    set(TMP_SOURCES_
+        ${TMP_SOURCES_}
+        ${CMAKE_CURRENT_LIST_DIR}/magma_fd.cpp
+    )
+endif()
+
 set(TMP_HEADERS_
     ${CMAKE_CURRENT_LIST_DIR}/hwinfo_linux.h
     ${CMAKE_CURRENT_LIST_DIR}/mos_context_specific.h
diff --git a/media_driver/linux/common/os/mos_auxtable_mgr.h b/media_driver/linux/common/os/mos_auxtable_mgr.h
index 8fbf59d..2c69138 100644
--- a/media_driver/linux/common/os/mos_auxtable_mgr.h
+++ b/media_driver/linux/common/os/mos_auxtable_mgr.h
@@ -27,7 +27,9 @@
 #ifndef MOS_AUXTABLE_MGR_H
 #define MOS_AUXTABLE_MGR_H
 
+#if !defined(USE_MAGMA)
 #include "xf86drm.h"
+#endif
 #include "drm.h"
 #include "i915_drm.h"
 #include "mos_bufmgr.h"
diff --git a/media_driver/linux/common/os/mos_interface.cpp b/media_driver/linux/common/os/mos_interface.cpp
index f2d5b4a..fcc0aec 100644
--- a/media_driver/linux/common/os/mos_interface.cpp
+++ b/media_driver/linux/common/os/mos_interface.cpp
@@ -433,7 +433,7 @@
 
     context->bIsAtomSOC           = false;
     context->bFreeContext         = true;
-#ifndef ANDROID
+#if !defined(ANDROID) && !defined(__Fuchsia__)
     {
         drm_i915_getparam_t gp;
         int32_t             ret   = -1;
@@ -453,6 +453,9 @@
             context->bKMDHasVCS2 = false;
         }
     }
+#else
+    //TODO(fxbug.dev/78281) - remove
+    fprintf(stderr, "%s:%d MosInterface::InitStreamParameters not implemented\n", __FILE__, __LINE__);
 #endif
 
     // read "Linux PerformanceTag Enable" user feature key
diff --git a/media_driver/linux/common/os/mos_os_specific.c b/media_driver/linux/common/os/mos_os_specific.c
index b6251e7..d730a61 100644
--- a/media_driver/linux/common/os/mos_os_specific.c
+++ b/media_driver/linux/common/os/mos_os_specific.c
@@ -1453,7 +1453,7 @@
         }
     }
 
-#ifndef ANDROID
+#if !defined(ANDROID) && !defined(__Fuchsia__)
     {
         drm_i915_getparam_t gp;
         int32_t             ret   = -1;
@@ -1483,6 +1483,9 @@
         eStatus = CreateIPC(pContext);
         MOS_CHK_STATUS_SAFE(eStatus);
     }
+#else
+    //TODO(fxbug.dev/78281) - remove
+    fprintf(stderr, "%s:%d Linux_InitContext not implemented\n", __FILE__, __LINE__);
 #endif
 
     pContext->pTranscryptedKernels      = nullptr;
@@ -7902,6 +7905,7 @@
 //!
 uint32_t Mos_Specific_GetTsFrequency(PMOS_INTERFACE osInterface)
 {
+#if defined(__linux__)
     int32_t freq = 0;
     drm_i915_getparam_t gp;
     MOS_ZeroMemory(&gp, sizeof(gp));
@@ -7917,6 +7921,10 @@
         // fail to query it from KMD
         return 0;
     }
+#else
+    fprintf(stderr, "%s:%d Mos_Specific_GetTsFrequency not implemented\n", __FILE__, __LINE__);
+    return 0;
+#endif
 }
 
 //!
diff --git a/media_driver/linux/common/os/mos_os_specific.h b/media_driver/linux/common/os/mos_os_specific.h
index a115e14..8555cf0 100644
--- a/media_driver/linux/common/os/mos_os_specific.h
+++ b/media_driver/linux/common/os/mos_os_specific.h
@@ -37,7 +37,9 @@
 #endif
 #include "i915_drm.h"
 #include "mos_bufmgr.h"
+#if !defined(USE_MAGMA)
 #include "xf86drm.h"
+#endif
 
 #include <vector>
 
diff --git a/media_driver/media_driver_next/linux/common/os/mos_os_specific_next.h b/media_driver/media_driver_next/linux/common/os/mos_os_specific_next.h
index 6fad66f..8b00c86 100644
--- a/media_driver/media_driver_next/linux/common/os/mos_os_specific_next.h
+++ b/media_driver/media_driver_next/linux/common/os/mos_os_specific_next.h
@@ -33,7 +33,9 @@
 #include "mos_defs.h"
 #include "i915_drm.h"
 #include "mos_bufmgr.h"
+#if !defined(USE_MAGMA)
 #include "xf86drm.h"
+#endif
 
 #include <vector>
 
diff --git a/media_driver/media_driver_next/media_srcs.cmake b/media_driver/media_driver_next/media_srcs.cmake
index e374bb5..f1d1862 100644
--- a/media_driver/media_driver_next/media_srcs.cmake
+++ b/media_driver/media_driver_next/media_srcs.cmake
@@ -20,7 +20,7 @@
 
 media_include_subdirectory(agnostic)
 
-if(${PLATFORM} STREQUAL "linux")
+if(${PLATFORM} STREQUAL "linux" OR ${PLATFORM} STREQUAL "Fuchsia")
    media_include_subdirectory(linux)
 else()
 endif()
diff --git a/media_driver/media_top_cmake.cmake b/media_driver/media_top_cmake.cmake
index 3f6f008..bbf51f2 100755
--- a/media_driver/media_top_cmake.cmake
+++ b/media_driver/media_top_cmake.cmake
@@ -25,6 +25,8 @@
 
 bs_set_if_undefined(LIB_NAME iHD_drv_video)
 
+option (USE_MAGMA "Use magma backend" OFF)
+
 option (MEDIA_RUN_TEST_SUITE "run google test module after install" ON) 
 include(${MEDIA_DRIVER_CMAKE}/media_gen_flags.cmake)
 include(${MEDIA_DRIVER_CMAKE}/media_feature_flags.cmake)
@@ -51,6 +53,7 @@
 message("-- media -- BUILD_TYPE/UFO_BUILD_TYPE/CMAKE_BUILD_TYPE = ${BUILD_TYPE}/${UFO_BUILD_TYPE}/${CMAKE_BUILD_TYPE}")
 message("-- media -- LIBVA_INSTALL_PATH = ${LIBVA_INSTALL_PATH}")
 message("-- media -- MEDIA_VERSION = ${MEDIA_VERSION}")
+message("-- media -- USE_MAGMA = ${USE_MAGMA}")
 if(X11_FOUND)
 message("-- media -- X11 Found")
 endif()