diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c
index a0a691dea3..cf552a5348 100644
--- a/gfx/video_shader_parse.c
+++ b/gfx/video_shader_parse.c
@@ -99,6 +99,39 @@ static void fill_pathname_expanded_and_absolute(char *out_path,
    pathname_conform_slashes_to_os(out_path);
 }
 
+static void gather_reference_path_list(struct path_linked_list *in_path_linked_list, 
+                                       char *path, 
+                                       int reference_depth)
+{
+   config_file_t *conf = NULL;
+   struct path_linked_list *reference_tmp = NULL;
+
+   if (reference_depth > SHADER_MAX_REFERENCE_DEPTH)
+      return;
+
+   conf = config_file_new_from_path_to_string(path);
+   if (conf)
+   {
+      reference_tmp = (struct path_linked_list*)conf->references;
+      while (reference_tmp)
+      {
+         char* reference_preset_path = (char*)malloc(PATH_MAX_LENGTH);
+
+         fill_pathname_expanded_and_absolute(reference_preset_path, conf->path, reference_tmp->path);
+         gather_reference_path_list(in_path_linked_list, reference_preset_path, reference_depth + 1);
+
+         free(reference_preset_path);
+         reference_tmp = reference_tmp->next;
+      }
+      path_linked_list_add_path(in_path_linked_list, path);
+   }
+   else
+   {
+      RARCH_WARN("\n            [Shaders]: No Preset located at \"%s\".\n", path);
+   }
+   config_file_free(conf);
+}
+
 /**
  * wrap_mode_to_str:
  * @type              : Wrap type.
@@ -851,6 +884,17 @@ end:
    return ret;
 }
 
+/* Check if the config is a valid shader chain config */
+static bool video_shader_is_shader_chain_config(config_file_t *conf)
+{
+   /* If the config has a shaders entry then it is considered 
+      a shader chain config, vs a config which may only have 
+      parameter values and texture overrides
+   */
+   
+   return config_get_entry(conf, "shaders");
+}
+
 static config_file_t *video_shader_get_root_preset_config(const char *path)
 {
    int reference_depth           = 1;
@@ -863,7 +907,7 @@ static config_file_t *video_shader_get_root_preset_config(const char *path)
       return NULL;
    }
 
-   while (conf->reference)
+   while (conf->references)
    {
       /* If we have reached the max depth of nested references,
        * stop attempting to read the next reference,
@@ -882,7 +926,7 @@ static config_file_t *video_shader_get_root_preset_config(const char *path)
       }
 
       /* Get the absolute path for the reference */
-      fill_pathname_expanded_and_absolute(nested_reference_path, conf->path, conf->reference);
+      fill_pathname_expanded_and_absolute(nested_reference_path, conf->path, conf->references->path);
 
       /* Create a new config from the referenced path */
       config_file_free(conf);
@@ -900,6 +944,7 @@ static config_file_t *video_shader_get_root_preset_config(const char *path)
    }
 
    free(nested_reference_path);
+
    return conf;
 }
 
@@ -950,7 +995,7 @@ static bool video_shader_check_reference_chain_for_save(
    {
       int reference_depth = 1;
 
-      while (conf->reference)
+      while (conf->references)
       {
          /* If we have reached the max depth of nested references stop attempting to read 
           * the next reference because we are likely in a self referential loop. */
@@ -963,7 +1008,7 @@ static bool video_shader_check_reference_chain_for_save(
          }
 
          /* Get the absolute path for the reference */
-         fill_pathname_expanded_and_absolute(nested_reference_path, conf->path, conf->reference);
+         fill_pathname_expanded_and_absolute(nested_reference_path, conf->path, conf->references->path);
 
          /* If one of the reference paths is the same as the file we want to save then this reference chain would be 
           * self-referential / cyclical and we can't save this as a simple preset*/
@@ -1106,11 +1151,11 @@ static bool video_shader_write_referenced_preset(
     * If there is a reference in the initially loaded preset,
     * we should check it against the preset path we are currently 
     * trying to save */
-   if (reference_conf->reference)
+   if (reference_conf->references)
    {
       /* Get the absolute path for the reference */
       fill_pathname_expanded_and_absolute(abs_temp_reference_path,
-            reference_conf->path, reference_conf->reference);
+            reference_conf->path, reference_conf->references->path);
 
       pathname_conform_slashes_to_os(abs_temp_reference_path);
 
@@ -1142,16 +1187,16 @@ static bool video_shader_write_referenced_preset(
 
    /* If the reference path is the same as the path we want to save 
     * or the reference path is in the config (auto shader) folder */
-   if (      string_is_equal(path_to_reference, path_to_save_conformed) 
+   if (string_is_equal(path_to_reference, path_to_save_conformed) 
          || !strncmp(config_dir, path_to_reference, strlen(config_dir)))
    {
       /* If the config from the reference path has a reference in it,
        * we will use this same nested reference for the new preset */
-      if (reference_conf->reference)
+      if (reference_conf->references)
       {
          /* Get the absolute path for the reference */
          fill_pathname_expanded_and_absolute(path_to_reference,
-               reference_conf->path, reference_conf->reference);
+               reference_conf->path, reference_conf->references->path);
 
          /* If the reference path is also the same as what 
           * we are trying to save 
@@ -1168,11 +1213,11 @@ static bool video_shader_write_referenced_preset(
                   path_to_reference);
 
             /* If the reference also has a reference inside it */
-            if (reference_conf->reference)
+            if (reference_conf->references)
             {
                /* Get the absolute path for the reference */
                fill_pathname_expanded_and_absolute(path_to_reference,
-                     reference_conf->path, reference_conf->reference);
+                     reference_conf->path, reference_conf->references->path);
             }
             /* If the config referenced is a full preset */
             else
@@ -1232,7 +1277,7 @@ static bool video_shader_write_referenced_preset(
    pathname_make_slashes_portable(relative_temp_reference_path);
 
    /* Add the reference path to the config */
-   config_file_set_reference_path(conf, path_to_reference);
+   config_file_add_reference(conf, path_to_reference);
 
    /* Set modified to true so when you run config_file_write 
     * it will save a file */
@@ -1715,6 +1760,7 @@ bool video_shader_write_preset(const char *path,
 }
 
 
+
 /**
  * video_shader_load_preset_into_shader:
  * @path              : Path to preset file, could be a 
@@ -1731,117 +1777,124 @@ bool video_shader_load_preset_into_shader(const char *path,
 {
    unsigned i                                        = 0;
    bool ret                                          = true;
-   char override_conf_paths[SHADER_MAX_REFERENCE_DEPTH][PATH_MAX_LENGTH];
    config_file_t *conf                               = NULL;
-   /* Get the root config, If we were able to get a root_config 
-    * that means the reference chain is valid */
-   config_file_t *root_conf                          = 
-      video_shader_get_root_preset_config(path);
+   config_file_t *root_conf                          = video_shader_get_root_preset_config(path);
+   struct path_linked_list* override_paths_list      = NULL;
+   struct path_linked_list* path_list_tmp            = NULL;
 
    if (!root_conf)
    {
-#ifdef DEBUG
       RARCH_LOG("\n");
       RARCH_WARN("[Shaders]: Could not read root preset: \"%s\".\n", path);
-#endif
       ret = false;
       goto end;
    }
 
-   /* If we were able to get a root_config that means that the 
-    * whole reference chain is valid */
-#ifdef DEBUG
-   RARCH_DBG("\n");
-#endif
-
-   video_shader_load_root_config_into_shader(root_conf,
-         config_get_ptr(), shader);
-   /* If the root_conf path matches the original path then 
-    * there are no references  so we just load it and go to the end */
-   if (string_is_equal(root_conf->path, path))
+   /* Check if the root preset is a valid shader chain */
+   if (!video_shader_is_shader_chain_config(root_conf))
+   {
+      RARCH_LOG("\n");
+      RARCH_WARN("[Shaders]: Root preset is not a valid shader chain because it has no shaders entry: \"%s\".\n", path);
+      ret = false;
       goto end;
+   }
+
+  /* If the root_conf path matches the original path then 
+    * there are no references so we just load it and go to the end */
+   if (string_is_equal(root_conf->path, path))
+   {
+      /* Load the config from the shader chain from the first reference into the shader */
+      video_shader_load_root_config_into_shader(root_conf, config_get_ptr(), shader);
+      goto end;
+   }
    
    /* Get the config from the initial preset file 
     * We don't need to check it's validity because it must 
     * have been valid to get the root preset */
    conf = config_file_new_from_path_to_string(path);
 
-   /* Set all override_conf_paths to empty so we know which 
-    * ones have been filled */
-   for (i = 0; i < SHADER_MAX_REFERENCE_DEPTH; i++)
-      override_conf_paths[i][0] = '\0';
-
-   i = 0;
-
 #ifdef DEBUG
-   RARCH_DBG("\n");
-   RARCH_DBG("[Shaders]: Crawl preset reference chain..\n");
+   RARCH_DBG("\n[Shaders]: Crawl preset reference chain..\n");
 #endif
 
-   /* If the config has a reference then we need gather all presets from the 
-    * chain of references to apply their values later */
-   while (conf->reference)
+   /**
+    * Check references starting with the second to make sure 
+    * they do not have a shader chains in them
+   **/
+   path_list_tmp = (struct path_linked_list*)conf->references->next;
+   while (path_list_tmp)
    {
-      char* reference_preset_path = (char*)malloc(PATH_MAX_LENGTH);
-      i++;
+      config_file_t *tmp_conf                      = NULL;
+      char *path_to_reference                = (char*)malloc(PATH_MAX_LENGTH);
 
-#ifdef DEBUG
-      RARCH_DBG("[Shaders]: Preset (depth %u): \"%s\".\n", i, conf->path);
-#endif
+      fill_pathname_expanded_and_absolute(path_to_reference, conf->path, path_list_tmp->path);
 
-      /* Add the reference to the list */
-      strlcpy(override_conf_paths[i], conf->path, PATH_MAX_LENGTH);
-
-      /* Get the absolute path for the reference */
-      fill_pathname_expanded_and_absolute(reference_preset_path,
-            conf->path, conf->reference);
-
-#ifdef DEBUG
-      RARCH_DBG("[Shaders]: #reference = \"%s\".\n",
-            reference_preset_path);
-#endif
-
-      /* Create a new config from this reference level */
-      config_file_free(conf);
-      conf = config_file_new_from_path_to_string(reference_preset_path);
-
-      free(reference_preset_path);
+      tmp_conf = video_shader_get_root_preset_config(path_to_reference);
+      if (tmp_conf)
+      {
+         if (video_shader_is_shader_chain_config(tmp_conf))
+         {
+            RARCH_WARN("\n[Shaders]: Additional #reference entries pointing at shader chain presets are not supported: \"%s\".\n", path_to_reference);
+            config_file_free(tmp_conf);
+            ret = false;
+            goto end;
+         }
+         else
+         {
+            config_file_free(tmp_conf);
+         }
+      }
+      else
+      {
+         RARCH_WARN("\n[Shaders]: Could not load root preset for #reference entry: \"%s\".\n", path_to_reference);
+         ret = false;
+         goto end;
+      }
+      path_list_tmp = path_list_tmp->next;
    }
-   
-   /* Step back through the references starting with the one 
-    * referencing the root config and apply overrides for each one */
+
+   /* Load the config from the shader chain from the first reference into the shader */
+   video_shader_load_root_config_into_shader(root_conf, config_get_ptr(), shader);
+
+   /* Set Path for originally loaded preset because it is different than the root preset path */
+   strlcpy(shader->loaded_preset_path, path, sizeof(shader->loaded_preset_path));
+
 #ifdef DEBUG
-   RARCH_DBG("\n");
-   RARCH_DBG("[Shaders]: Start applying simple preset overrides..\n");
+   RARCH_DBG("\n[Shaders]: Start applying simple preset overrides..\n");
 #endif
 
-   while (i)
+   /* Gather all the paths of all of the presets in all reference chains */
+   override_paths_list = path_linked_list_new();
+   gather_reference_path_list(override_paths_list, conf->path, 0);
+
+   /* 
+    * Step through the references and apply overrides for each one
+    * Start on the second item since the first is empty 
+   */
+   path_list_tmp = (struct path_linked_list*)override_paths_list;
+   while (path_list_tmp)
    {
-      config_file_t *override_conf = config_file_new_from_path_to_string(
-            override_conf_paths[i]);
+      config_file_t *override_conf                      = NULL;
+      
+      override_conf = config_file_new_from_path_to_string(path_list_tmp->path);
       
 #ifdef DEBUG
       RARCH_DBG("[Shaders]: Depth %u apply overrides..\n", i);
-      RARCH_DBG("[Shaders]: Apply values from: \"%s\".\n",
-            override_conf->path);
+      RARCH_DBG("[Shaders]: Apply values from: \"%s\".\n", override_conf->path);
 #endif
+
       override_shader_values(override_conf, shader);
-
       config_file_free(override_conf);
-      i--;
+      path_list_tmp = path_list_tmp->next;
    }
-
+   
 #ifdef DEBUG
-   RARCH_DBG("[Shaders]: End apply overrides.\n");
-   RARCH_DBG("\n");
+   RARCH_DBG("[Shaders]: End apply overrides.\n\n");
 #endif
 
-   /* Set Path for originally loaded preset because it is 
-    * different than the root preset path */
-   strlcpy( shader->loaded_preset_path, path,
-         sizeof(shader->loaded_preset_path));
 end:
 
+   path_linked_list_free(override_paths_list);
    config_file_free(conf);
    config_file_free(root_conf);
 
diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c
index 507091a815..cc3b74c333 100644
--- a/libretro-common/file/config_file.c
+++ b/libretro-common/file/config_file.c
@@ -408,6 +408,20 @@ static void config_file_add_sub_conf(config_file_t *conf, char *path,
          conf->path);
 }
 
+void config_file_add_reference(config_file_t *conf, char *path)
+{
+   /* It is expected that the conf has it's path already set */
+   char short_path[PATH_MAX_LENGTH];
+   
+   short_path[0] = '\0';
+   
+   if (!conf->references)
+      conf->references = path_linked_list_new();
+
+   fill_pathname_abbreviated_or_relative(short_path, conf->path, path, sizeof(short_path));
+   path_linked_list_add_path(conf->references, short_path);
+}
+
 static int config_file_load_internal(
       struct config_file *conf,
       const char *path, unsigned depth, config_file_cb_t *cb)
@@ -581,7 +595,7 @@ static bool config_file_parse_line(config_file_t *conf,
          if (!path)
             return false;
 
-         config_file_set_reference_path(conf, path);
+         config_file_add_reference(conf, path);
 
          if (!path)
             return false;
@@ -702,32 +716,13 @@ static int config_file_from_string_internal(
    return 0;
 }
 
-void config_file_set_reference_path(config_file_t *conf, char *path)
-{
-   /* It is expected that the conf has it's path already set */
-   
-   char short_path[PATH_MAX_LENGTH];
-   
-   short_path[0] = '\0';
-
-   if (!conf)
-      return;
-
-   if (conf->reference)
-   {
-      free(conf->reference);
-      conf->reference = NULL;
-   }
-
-   fill_pathname_abbreviated_or_relative(short_path, conf->path, path, sizeof(short_path));
-   
-   conf->reference = strdup(short_path);
-}
 
 bool config_file_deinitialize(config_file_t *conf)
 {
    struct config_include_list *inc_tmp = NULL;
    struct config_entry_list *tmp       = NULL;
+   struct path_linked_list *ref_tmp = NULL;
+
    if (!conf)
       return false;
 
@@ -762,8 +757,7 @@ bool config_file_deinitialize(config_file_t *conf)
          free(hold);
    }
 
-   if (conf->reference)
-      free(conf->reference);
+   path_linked_list_free(conf->references);
 
    if (conf->path)
       free(conf->path);
@@ -905,7 +899,7 @@ void config_file_initialize(struct config_file *conf)
    conf->entries                  = NULL;
    conf->tail                     = NULL;
    conf->last                     = NULL;
-   conf->reference                = NULL;
+   conf->references               = NULL;
    conf->includes                 = NULL;
    conf->include_depth            = 0;
    conf->guaranteed_no_duplicates = false;
@@ -1363,11 +1357,13 @@ void config_file_dump(config_file_t *conf, FILE *file, bool sort)
 {
    struct config_entry_list       *list = NULL;
    struct config_include_list *includes = conf->includes;
+   struct path_linked_list *ref_tmp = conf->references;
 
-   if (conf->reference)
+   while (ref_tmp)
    {
-      pathname_make_slashes_portable(conf->reference);
-      fprintf(file, "#reference \"%s\"\n", conf->reference);
+      pathname_make_slashes_portable(ref_tmp->path);
+      fprintf(file, "#reference \"%s\"\n", ref_tmp->path);
+      ref_tmp = ref_tmp->next;
    }
 
    if (sort)
diff --git a/libretro-common/file/file_path.c b/libretro-common/file/file_path.c
index 320c5a2daa..36c20f1b09 100644
--- a/libretro-common/file/file_path.c
+++ b/libretro-common/file/file_path.c
@@ -70,6 +70,76 @@
 
 #endif
 
+/**
+ * Create a new linked list with one node in it
+ * The path on this node will be set to NULL
+**/
+struct path_linked_list* path_linked_list_new()
+{
+   struct path_linked_list* paths_list = (struct path_linked_list*)malloc(sizeof(*paths_list));
+   paths_list->next = NULL;
+   paths_list->path = NULL;
+   return paths_list;
+}
+
+/* Free the entire linked list */
+bool path_linked_list_free(struct path_linked_list *in_path_linked_list)
+{
+   struct path_linked_list *node_tmp = NULL;
+
+   node_tmp = (struct path_linked_list*)in_path_linked_list;
+   while (node_tmp)
+   {
+      struct path_linked_list *hold = NULL;
+      if (node_tmp->path)
+         free(node_tmp->path);
+      hold    = (struct path_linked_list*)node_tmp;
+      node_tmp = node_tmp->next;
+      if (hold)
+         free(hold);
+   }
+
+   return true;
+}
+
+/**
+ * Add a node to the linked list with this path
+ * If the first node's path if it's not yet set the path
+ * on this node instead
+**/
+void path_linked_list_add_path(struct path_linked_list *in_path_linked_list, char *path)
+{
+    /* If the first item does not have a path this is
+      a list which has just been created, so we just fill 
+      the path for the first item
+   */
+   if (!in_path_linked_list->path)
+   {
+      in_path_linked_list->path = strdup(path);
+   }
+   else
+   {  
+      struct path_linked_list *head = in_path_linked_list;
+      struct path_linked_list *node = (struct path_linked_list*) malloc(sizeof(*node));
+
+      if (node)
+      {
+         node->next        = NULL;
+         node->path        = strdup(path);
+
+         if (head)
+         {
+            while (head->next)
+               head        = head->next;
+
+            head->next     = node;
+         }
+         else
+            in_path_linked_list = node;
+      }
+   }
+}
+
 /**
  * path_get_archive_delim:
  * @path               : path
diff --git a/libretro-common/include/file/config_file.h b/libretro-common/include/file/config_file.h
index 014d5ba722..6c48b5bd81 100644
--- a/libretro-common/include/file/config_file.h
+++ b/libretro-common/include/file/config_file.h
@@ -54,12 +54,12 @@ RETRO_BEGIN_DECLS
 struct config_file
 {
    char *path;
-   char *reference;
    struct config_entry_list **entries_map;
    struct config_entry_list *entries;
    struct config_entry_list *tail;
    struct config_entry_list *last;
    struct config_include_list *includes;
+   struct path_linked_list *references;
    unsigned include_depth;
    bool guaranteed_no_duplicates;
    bool modified;
@@ -109,7 +109,7 @@ config_file_t *config_file_new_from_path_to_string(const char *path);
 /* Frees config file. */
 void config_file_free(config_file_t *conf);
 
-void config_file_set_reference_path(config_file_t *conf, char *path);
+void config_file_add_reference(config_file_t *conf, char *path);
 
 bool config_file_deinitialize(config_file_t *conf);
 
diff --git a/libretro-common/include/file/file_path.h b/libretro-common/include/file/file_path.h
index 452763fed2..4b54dc42d1 100644
--- a/libretro-common/include/file/file_path.h
+++ b/libretro-common/include/file/file_path.h
@@ -51,6 +51,28 @@ enum
    RARCH_FILE_UNSUPPORTED
 };
 
+struct path_linked_list
+{
+   char *path;
+   struct path_linked_list *next;
+};
+
+/**
+ * Create a new linked list with one item in it
+ * The path on this item will be set to NULL
+**/
+struct path_linked_list* path_linked_list_new();
+
+/* Free the entire linked list */
+bool path_linked_list_free(struct path_linked_list *in_path_linked_list);
+
+/**
+ * Add a node to the linked list with this path
+ * If the first node's path if it's not yet set, 
+ * set this instead
+**/
+void path_linked_list_add_path(struct path_linked_list *in_path_linked_list, char *path);
+
 /**
  * path_is_compressed_file:
  * @path               : path