diff --git a/.gitignore b/.gitignore
index 7f0455b..c1e0cac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,6 @@
 librashader_runtime_*.exe
 /test/capi-tests/librashader-capi-tests/.vs/
 /test/capi-tests/librashader-capi-tests/x64/
-/test/capi-tests/librashader-capi-tests/librashader-capi-tests/x64/
-/test/capi-tests/librashader-capi-tests/librashader-capi-tests/*.so
-/test/capi-tests/librashader-capi-tests/librashader-capi-tests/*.out
+/test/capi-tests/librashader-capi-tests/**/x64/
+/test/capi-tests/librashader-capi-tests/**/*.so
+/test/capi-tests/librashader-capi-tests/**/*.out
diff --git a/.gitmodules b/.gitmodules
index ba5f1ee..26625c6 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,3 +4,6 @@
 [submodule "naga"]
 	path = naga
 	url = https://github.com/chyyran/naga
+[submodule "test/capi-tests/librashader-capi-tests/dx11-example/external/crosswindow"]
+	path = test/capi-tests/librashader-capi-tests/dx11-example/external/crosswindow
+	url = https://github.com/alaingalvan/crosswindow.git
diff --git a/README.md b/README.md
index 0f89922..ef2a3f7 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,16 @@ Linking against `librashader.h` directly is possible, but is not officially supp
 parameters are correct in order to successfully link with `librashader.lib` or `librashader.a`. The [corrosion](https://github.com/corrosion-rs/)
 CMake package is highly recommended.
 
+### Examples
+
+The following Rust examples show how to use each librashader runtime.
+* [Vulkan](https://github.com/SnowflakePowered/librashader/blob/master/librashader-runtime-vk/src/lib.rs#L40)
+* [OpenGL](https://github.com/SnowflakePowered/librashader/blob/master/librashader-runtime-gl/src/lib.rs#L34)
+* [Direct3D 11](https://github.com/SnowflakePowered/librashader/blob/master/librashader-runtime-d3d11/src/lib.rs#L33)
+
+Some basic examples on using the C API are also provided in the [librashader-capi-tests](https://github.com/SnowflakePowered/librashader/tree/master/test/capi-tests/librashader-capi-tests)
+directory.
+
 ## Compatibility
 
 librashader implements the entire RetroArch shader pipeline and is highly compatible with existing shaders,
diff --git a/test/capi-tests/librashader-capi-tests/dx11-example/dx11-example.vcxproj b/test/capi-tests/librashader-capi-tests/dx11-example/dx11-example.vcxproj
new file mode 100644
index 0000000..5d4fea3
--- /dev/null
+++ b/test/capi-tests/librashader-capi-tests/dx11-example/dx11-example.vcxproj
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>16.0</VCProjectVersion>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectGuid>{acde0543-c068-456d-b4c0-6c5e39296abb}</ProjectGuid>
+    <RootNamespace>dx11example</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <LanguageStandard>stdcpp20</LanguageStandard>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <LanguageStandard>stdcpp20</LanguageStandard>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="main.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <FxCompile Include="shaders.hlsl">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+    </FxCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\include\librashader.h" />
+    <ClInclude Include="..\..\..\..\include\librashader_ld.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/test/capi-tests/librashader-capi-tests/dx11-example/dx11-example.vcxproj.filters b/test/capi-tests/librashader-capi-tests/dx11-example/dx11-example.vcxproj.filters
new file mode 100644
index 0000000..8511690
--- /dev/null
+++ b/test/capi-tests/librashader-capi-tests/dx11-example/dx11-example.vcxproj.filters
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="main.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <FxCompile Include="shaders.hlsl" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\include\librashader.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\include\librashader_ld.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/test/capi-tests/librashader-capi-tests/dx11-example/dx11-example.vcxproj.user b/test/capi-tests/librashader-capi-tests/dx11-example/dx11-example.vcxproj.user
new file mode 100644
index 0000000..88a5509
--- /dev/null
+++ b/test/capi-tests/librashader-capi-tests/dx11-example/dx11-example.vcxproj.user
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup />
+</Project>
\ No newline at end of file
diff --git a/test/capi-tests/librashader-capi-tests/dx11-example/main.cpp b/test/capi-tests/librashader-capi-tests/dx11-example/main.cpp
new file mode 100644
index 0000000..882e22e
--- /dev/null
+++ b/test/capi-tests/librashader-capi-tests/dx11-example/main.cpp
@@ -0,0 +1,411 @@
+// based off https://github.com/kevinmoran/BeginnerDirect3D11/tree/master/02.%20Drawing%20a%20Triangle
+#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
+#define UNICODE
+#include <d3d11_1.h>
+#include <windows.h>
+#pragma comment(lib, "d3d11.lib")
+#include <d3dcompiler.h>
+#pragma comment(lib, "d3dcompiler.lib")
+
+#include <assert.h>
+#define LIBRA_RUNTIME_D3D11
+
+#include "../../../../include/librashader.h"
+#include "../../../../include/librashader_ld.h"
+
+
+static bool global_windowDidResize = false;
+
+LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
+    LRESULT result = 0;
+    switch (msg) {
+        case WM_KEYDOWN: {
+            if (wparam == VK_ESCAPE) DestroyWindow(hwnd);
+            break;
+        }
+        case WM_DESTROY: {
+            PostQuitMessage(0);
+            break;
+        }
+        case WM_SIZE: {
+            global_windowDidResize = true;
+            break;
+        }
+        default:
+            result = DefWindowProcW(hwnd, msg, wparam, lparam);
+    }
+    return result;
+}
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/,
+                   LPSTR /*lpCmdLine*/, int /*nShowCmd*/) {
+    // Open a window
+    HWND hwnd;
+    {
+        WNDCLASSEXW winClass = {};
+        winClass.cbSize = sizeof(WNDCLASSEXW);
+        winClass.style = CS_HREDRAW | CS_VREDRAW;
+        winClass.lpfnWndProc = &WndProc;
+        winClass.hInstance = hInstance;
+        winClass.hIcon = LoadIconW(0, IDI_APPLICATION);
+        winClass.hCursor = LoadCursorW(0, IDC_ARROW);
+        winClass.lpszClassName = L"MyWindowClass";
+        winClass.hIconSm = LoadIconW(0, IDI_APPLICATION);
+
+        if (!RegisterClassExW(&winClass)) {
+            MessageBoxA(0, "RegisterClassEx failed", "Fatal Error", MB_OK);
+            return GetLastError();
+        }
+
+        RECT initialRect = {0, 0, 1024, 768};
+        AdjustWindowRectEx(&initialRect, WS_OVERLAPPEDWINDOW, FALSE,
+                           WS_EX_OVERLAPPEDWINDOW);
+        LONG initialWidth = initialRect.right - initialRect.left;
+        LONG initialHeight = initialRect.bottom - initialRect.top;
+
+        hwnd = CreateWindowExW(WS_EX_OVERLAPPEDWINDOW, winClass.lpszClassName,
+                               L"librashader-capi DirectX 11",
+                               WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT,
+                               CW_USEDEFAULT, initialWidth, initialHeight, 0, 0,
+                               hInstance, 0);
+
+        if (!hwnd) {
+            MessageBoxA(0, "CreateWindowEx failed", "Fatal Error", MB_OK);
+            return GetLastError();
+        }
+    }
+
+    // Create D3D11 Device and Context
+    ID3D11Device1* d3d11Device;
+    ID3D11DeviceContext1* d3d11DeviceContext;
+    {
+        ID3D11Device* baseDevice;
+        ID3D11DeviceContext* baseDeviceContext;
+        D3D_FEATURE_LEVEL featureLevels[] = {D3D_FEATURE_LEVEL_11_0};
+        UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
+#if defined(DEBUG_BUILD)
+        creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
+#endif
+
+        HRESULT hResult = D3D11CreateDevice(
+            0, D3D_DRIVER_TYPE_HARDWARE, 0, creationFlags, featureLevels,
+            ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &baseDevice, 0,
+            &baseDeviceContext);
+        if (FAILED(hResult)) {
+            MessageBoxA(0, "D3D11CreateDevice() failed", "Fatal Error", MB_OK);
+            return GetLastError();
+        }
+
+        // Get 1.1 interface of D3D11 Device and Context
+        hResult = baseDevice->QueryInterface(__uuidof(ID3D11Device1),
+                                             (void**)&d3d11Device);
+        assert(SUCCEEDED(hResult));
+        baseDevice->Release();
+
+        hResult = baseDeviceContext->QueryInterface(
+            __uuidof(ID3D11DeviceContext1), (void**)&d3d11DeviceContext);
+        assert(SUCCEEDED(hResult));
+        baseDeviceContext->Release();
+    }
+
+#ifdef DEBUG_BUILD
+    // Set up debug layer to break on D3D11 errors
+    ID3D11Debug* d3dDebug = nullptr;
+    d3d11Device->QueryInterface(__uuidof(ID3D11Debug), (void**)&d3dDebug);
+    if (d3dDebug) {
+        ID3D11InfoQueue* d3dInfoQueue = nullptr;
+        if (SUCCEEDED(d3dDebug->QueryInterface(__uuidof(ID3D11InfoQueue),
+                                               (void**)&d3dInfoQueue))) {
+            d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION,
+                                             true);
+            d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR,
+                                             true);
+            d3dInfoQueue->Release();
+        }
+        d3dDebug->Release();
+    }
+#endif
+
+    auto libra = librashader_load_instance();
+    libra_shader_preset_t preset;
+        auto error = libra.preset_create(
+        "../../../slang-shaders/border/gameboy-player/"
+        "gameboy-player-crt-royale.slangp",
+        &preset);
+
+    libra_d3d11_filter_chain_t filter_chain;
+
+    libra.d3d11_filter_chain_create(&preset, NULL, d3d11Device,
+                                    &filter_chain);
+
+    // Create Swap Chain
+    IDXGISwapChain1* d3d11SwapChain;
+    {
+        // Get DXGI Factory (needed to create Swap Chain)
+        IDXGIFactory2* dxgiFactory;
+        {
+            IDXGIDevice1* dxgiDevice;
+            HRESULT hResult = d3d11Device->QueryInterface(
+                __uuidof(IDXGIDevice1), (void**)&dxgiDevice);
+            assert(SUCCEEDED(hResult));
+
+            IDXGIAdapter* dxgiAdapter;
+            hResult = dxgiDevice->GetAdapter(&dxgiAdapter);
+            assert(SUCCEEDED(hResult));
+            dxgiDevice->Release();
+
+            DXGI_ADAPTER_DESC adapterDesc;
+            dxgiAdapter->GetDesc(&adapterDesc);
+
+            OutputDebugStringA("Graphics Device: ");
+            OutputDebugStringW(adapterDesc.Description);
+
+            hResult = dxgiAdapter->GetParent(__uuidof(IDXGIFactory2),
+                                             (void**)&dxgiFactory);
+            assert(SUCCEEDED(hResult));
+            dxgiAdapter->Release();
+        }
+
+        DXGI_SWAP_CHAIN_DESC1 d3d11SwapChainDesc = {};
+        d3d11SwapChainDesc.Width = 0;     // use window width
+        d3d11SwapChainDesc.Height = 0;    // use window height
+        d3d11SwapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
+        d3d11SwapChainDesc.SampleDesc.Count = 1;
+        d3d11SwapChainDesc.SampleDesc.Quality = 0;
+        d3d11SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+        d3d11SwapChainDesc.BufferCount = 2;
+        d3d11SwapChainDesc.Scaling = DXGI_SCALING_STRETCH;
+        d3d11SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+        d3d11SwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
+        d3d11SwapChainDesc.Flags = 0;
+
+        HRESULT hResult = dxgiFactory->CreateSwapChainForHwnd(
+            d3d11Device, hwnd, &d3d11SwapChainDesc, 0, 0, &d3d11SwapChain);
+        assert(SUCCEEDED(hResult));
+
+        dxgiFactory->Release();
+    }
+
+    // Create Framebuffer Render Target
+    ID3D11RenderTargetView* d3d11FrameBufferView;
+    {
+        ID3D11Texture2D* d3d11FrameBuffer;
+        HRESULT hResult = d3d11SwapChain->GetBuffer(
+            0, __uuidof(ID3D11Texture2D), (void**)&d3d11FrameBuffer);
+        assert(SUCCEEDED(hResult));
+
+        hResult = d3d11Device->CreateRenderTargetView(d3d11FrameBuffer, 0,
+                                                      &d3d11FrameBufferView);
+        assert(SUCCEEDED(hResult));
+        d3d11FrameBuffer->Release();
+    }
+
+    // Create Vertex Shader
+    ID3DBlob* vsBlob;
+    ID3D11VertexShader* vertexShader;
+    {
+        ID3DBlob* shaderCompileErrorsBlob;
+        HRESULT hResult = D3DCompileFromFile(L"shaders.hlsl", nullptr, nullptr,
+                                             "vs_main", "vs_5_0", 0, 0, &vsBlob,
+                                             &shaderCompileErrorsBlob);
+        if (FAILED(hResult)) {
+            const char* errorString = NULL;
+            if (hResult == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
+                errorString = "Could not compile shader; file not found";
+            else if (shaderCompileErrorsBlob) {
+                errorString =
+                    (const char*)shaderCompileErrorsBlob->GetBufferPointer();
+                shaderCompileErrorsBlob->Release();
+            }
+            MessageBoxA(0, errorString, "Shader Compiler Error",
+                        MB_ICONERROR | MB_OK);
+            return 1;
+        }
+
+        hResult = d3d11Device->CreateVertexShader(vsBlob->GetBufferPointer(),
+                                                  vsBlob->GetBufferSize(),
+                                                  nullptr, &vertexShader);
+        assert(SUCCEEDED(hResult));
+    }
+
+    // Create Pixel Shader
+    ID3D11PixelShader* pixelShader;
+    {
+        ID3DBlob* psBlob;
+        ID3DBlob* shaderCompileErrorsBlob;
+        HRESULT hResult = D3DCompileFromFile(L"shaders.hlsl", nullptr, nullptr,
+                                             "ps_main", "ps_5_0", 0, 0, &psBlob,
+                                             &shaderCompileErrorsBlob);
+        if (FAILED(hResult)) {
+            const char* errorString = NULL;
+            if (hResult == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
+                errorString = "Could not compile shader; file not found";
+            else if (shaderCompileErrorsBlob) {
+                errorString =
+                    (const char*)shaderCompileErrorsBlob->GetBufferPointer();
+                shaderCompileErrorsBlob->Release();
+            }
+            MessageBoxA(0, errorString, "Shader Compiler Error",
+                        MB_ICONERROR | MB_OK);
+            return 1;
+        }
+
+        hResult = d3d11Device->CreatePixelShader(psBlob->GetBufferPointer(),
+                                                 psBlob->GetBufferSize(),
+                                                 nullptr, &pixelShader);
+        assert(SUCCEEDED(hResult));
+        psBlob->Release();
+    }
+
+    // Create Input Layout
+    ID3D11InputLayout* inputLayout;
+    {
+        D3D11_INPUT_ELEMENT_DESC inputElementDesc[] = {
+            {"POS", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0,
+             D3D11_INPUT_PER_VERTEX_DATA, 0},
+            {"COL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0,
+             D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}};
+
+        HRESULT hResult = d3d11Device->CreateInputLayout(
+            inputElementDesc, ARRAYSIZE(inputElementDesc),
+            vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), &inputLayout);
+        assert(SUCCEEDED(hResult));
+        vsBlob->Release();
+    }
+
+    // Create Vertex Buffer
+    ID3D11Buffer* vertexBuffer;
+    UINT numVerts;
+    UINT stride;
+    UINT offset;
+    {
+        float vertexData[] = {// x, y, r, g, b, a
+                              0.0f,  0.5f,  0.f, 1.f, 0.f, 1.f,
+                              0.5f,  -0.5f, 1.f, 0.f, 0.f, 1.f,
+                              -0.5f, -0.5f, 0.f, 0.f, 1.f, 1.f};
+        stride = 6 * sizeof(float);
+        numVerts = sizeof(vertexData) / stride;
+        offset = 0;
+
+        D3D11_BUFFER_DESC vertexBufferDesc = {};
+        vertexBufferDesc.ByteWidth = sizeof(vertexData);
+        vertexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
+        vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+
+        D3D11_SUBRESOURCE_DATA vertexSubresourceData = {vertexData};
+
+        HRESULT hResult = d3d11Device->CreateBuffer(
+            &vertexBufferDesc, &vertexSubresourceData, &vertexBuffer);
+        assert(SUCCEEDED(hResult));
+    }
+
+    // Main Loop
+    bool isRunning = true;
+    size_t frameCount = 0;
+
+    while (isRunning) {
+        MSG msg = {};
+        while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) {
+            if (msg.message == WM_QUIT) isRunning = false;
+            TranslateMessage(&msg);
+            DispatchMessageW(&msg);
+        }
+
+        if (global_windowDidResize) {
+            d3d11DeviceContext->OMSetRenderTargets(0, 0, 0);
+            d3d11FrameBufferView->Release();
+
+            HRESULT res =
+                d3d11SwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
+            assert(SUCCEEDED(res));
+
+            ID3D11Texture2D* d3d11FrameBuffer;
+            res = d3d11SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D),
+                                            (void**)&d3d11FrameBuffer);
+            assert(SUCCEEDED(res));
+
+            res = d3d11Device->CreateRenderTargetView(d3d11FrameBuffer, NULL,
+                                                      &d3d11FrameBufferView);
+            assert(SUCCEEDED(res));
+            d3d11FrameBuffer->Release();
+
+            global_windowDidResize = false;
+        }
+
+        FLOAT backgroundColor[4] = {0.1f, 0.2f, 0.6f, 1.0f};
+        d3d11DeviceContext->ClearRenderTargetView(d3d11FrameBufferView,
+                                                  backgroundColor);
+
+        RECT winRect;
+        GetClientRect(hwnd, &winRect);
+        D3D11_VIEWPORT viewport = {0.0f,
+                                   0.0f,
+                                   (FLOAT)(winRect.right - winRect.left),
+                                   (FLOAT)(winRect.bottom - winRect.top),
+                                   0.0f,
+                                   1.0f};
+        d3d11DeviceContext->RSSetViewports(1, &viewport);
+
+        d3d11DeviceContext->OMSetRenderTargets(1, &d3d11FrameBufferView,
+                                               nullptr);
+
+        d3d11DeviceContext->IASetPrimitiveTopology(
+            D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+        d3d11DeviceContext->IASetInputLayout(inputLayout);
+
+        d3d11DeviceContext->VSSetShader(vertexShader, nullptr, 0);
+        d3d11DeviceContext->PSSetShader(pixelShader, nullptr, 0);
+
+        d3d11DeviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride,
+                                               &offset);
+
+        d3d11DeviceContext->Draw(numVerts, 0);
+
+        ID3D11Texture2D* framebufferCopy;
+        ID3D11ShaderResourceView* copySrv;
+        {
+            ID3D11Texture2D* d3d11FrameBuffer;
+            HRESULT hResult = d3d11SwapChain->GetBuffer(
+                0, __uuidof(ID3D11Texture2D), (void**)&d3d11FrameBuffer);
+            assert(SUCCEEDED(hResult));
+
+            D3D11_TEXTURE2D_DESC framebufferDesc;
+            d3d11FrameBuffer->GetDesc(&framebufferDesc);
+
+            framebufferDesc.BindFlags =
+                D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
+            framebufferDesc.CPUAccessFlags =
+                D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_READ;
+
+            hResult = d3d11Device->CreateTexture2D(&framebufferDesc, nullptr,
+                                                   &framebufferCopy);
+            assert(SUCCEEDED(hResult));
+
+            d3d11DeviceContext->CopyResource(framebufferCopy, d3d11FrameBuffer);
+
+            hResult = d3d11Device->CreateShaderResourceView(framebufferCopy, 0,
+                                                            &copySrv);
+            assert(SUCCEEDED(hResult));
+
+            d3d11FrameBuffer->Release();
+        }
+
+        assert(copySrv != nullptr);
+
+        libra_source_image_d3d11_t input = {copySrv, viewport.Height,
+                                            viewport.Width};
+
+        libra_viewport_t vp = {0, 0, viewport.Height, viewport.Width};
+
+        libra.d3d11_filter_chain_frame(&filter_chain, frameCount, input, vp,
+                                       d3d11FrameBufferView, NULL, NULL);
+
+        copySrv->Release();
+        framebufferCopy->Release();
+        d3d11SwapChain->Present(1, 0);
+        frameCount += 1;
+    }
+
+    return 0;
+}
\ No newline at end of file
diff --git a/test/capi-tests/librashader-capi-tests/dx11-example/shaders.hlsl b/test/capi-tests/librashader-capi-tests/dx11-example/shaders.hlsl
new file mode 100644
index 0000000..9cb8f52
--- /dev/null
+++ b/test/capi-tests/librashader-capi-tests/dx11-example/shaders.hlsl
@@ -0,0 +1,20 @@
+
+struct VS_Input {
+    float2 pos : POS;
+    float4 color : COL;
+};
+
+struct VS_Output {
+    float4 position : SV_POSITION;
+    float4 color : COL;
+};
+
+VS_Output vs_main(VS_Input input) {
+    VS_Output output;
+    output.position = float4(input.pos, 0.0f, 1.0f);
+    output.color = input.color;
+
+    return output;
+}
+
+float4 ps_main(VS_Output input) : SV_TARGET { return input.color; }
\ No newline at end of file
diff --git a/test/capi-tests/librashader-capi-tests/librashader-capi-tests.sln b/test/capi-tests/librashader-capi-tests/librashader-capi-tests.sln
index 69ea1e9..d897ad6 100644
--- a/test/capi-tests/librashader-capi-tests/librashader-capi-tests.sln
+++ b/test/capi-tests/librashader-capi-tests/librashader-capi-tests.sln
@@ -5,6 +5,8 @@ VisualStudioVersion = 17.4.32912.340
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "librashader-capi-tests", "librashader-capi-tests\librashader-capi-tests.vcxproj", "{0B017393-E288-4467-BEBA-F89F7CD8E5D4}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dx11-example", "dx11-example\dx11-example.vcxproj", "{ACDE0543-C068-456D-B4C0-6C5E39296ABB}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|x64 = Debug|x64
@@ -21,6 +23,14 @@ Global
 		{0B017393-E288-4467-BEBA-F89F7CD8E5D4}.Release|x64.Build.0 = Release|x64
 		{0B017393-E288-4467-BEBA-F89F7CD8E5D4}.Release|x86.ActiveCfg = Release|Win32
 		{0B017393-E288-4467-BEBA-F89F7CD8E5D4}.Release|x86.Build.0 = Release|Win32
+		{ACDE0543-C068-456D-B4C0-6C5E39296ABB}.Debug|x64.ActiveCfg = Debug|x64
+		{ACDE0543-C068-456D-B4C0-6C5E39296ABB}.Debug|x64.Build.0 = Debug|x64
+		{ACDE0543-C068-456D-B4C0-6C5E39296ABB}.Debug|x86.ActiveCfg = Debug|Win32
+		{ACDE0543-C068-456D-B4C0-6C5E39296ABB}.Debug|x86.Build.0 = Debug|Win32
+		{ACDE0543-C068-456D-B4C0-6C5E39296ABB}.Release|x64.ActiveCfg = Release|x64
+		{ACDE0543-C068-456D-B4C0-6C5E39296ABB}.Release|x64.Build.0 = Release|x64
+		{ACDE0543-C068-456D-B4C0-6C5E39296ABB}.Release|x86.ActiveCfg = Release|Win32
+		{ACDE0543-C068-456D-B4C0-6C5E39296ABB}.Release|x86.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/test/capi-tests/librashader-capi-tests/librashader-capi-tests/librashader-capi-tests.cpp b/test/capi-tests/librashader-capi-tests/librashader-capi-tests/librashader-capi-tests.cpp
index aed50f1..f7ad773 100644
--- a/test/capi-tests/librashader-capi-tests/librashader-capi-tests/librashader-capi-tests.cpp
+++ b/test/capi-tests/librashader-capi-tests/librashader-capi-tests/librashader-capi-tests.cpp
@@ -16,6 +16,11 @@ int main()
         "gameboy-player-crt-royale.slangp",
         &preset);
 
+    libra_shader_preset_t preset2;
+    libra_preset_create(
+        "../../../slang-shaders/border/gameboy-player/"
+        "gameboy-player-crt-royale.slangp",
+        &preset2);
     
     instance.preset_print(&preset);
     std::cout << "printed\n";
diff --git a/test/capi-tests/librashader-capi-tests/librashader-capi-tests/librashader-capi-tests.vcxproj b/test/capi-tests/librashader-capi-tests/librashader-capi-tests/librashader-capi-tests.vcxproj
index 3da400e..b7d35c4 100644
--- a/test/capi-tests/librashader-capi-tests/librashader-capi-tests/librashader-capi-tests.vcxproj
+++ b/test/capi-tests/librashader-capi-tests/librashader-capi-tests/librashader-capi-tests.vcxproj
@@ -146,7 +146,7 @@
     <ClInclude Include="..\..\..\..\include\librashader_ld.h" />
   </ItemGroup>
   <ItemGroup>
-    <Library Include="..\..\..\..\target\debug\librashader.dll.lib" />
+    <Library Include="..\..\..\..\target\debug\librashader.lib" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
diff --git a/test/capi-tests/librashader-capi-tests/librashader-capi-tests/librashader-capi-tests.vcxproj.filters b/test/capi-tests/librashader-capi-tests/librashader-capi-tests/librashader-capi-tests.vcxproj.filters
index d3145c2..c1a2512 100644
--- a/test/capi-tests/librashader-capi-tests/librashader-capi-tests/librashader-capi-tests.vcxproj.filters
+++ b/test/capi-tests/librashader-capi-tests/librashader-capi-tests/librashader-capi-tests.vcxproj.filters
@@ -20,15 +20,14 @@
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
-    <Library Include="..\..\..\..\target\debug\librashader_capi.lib" />
-    <Library Include="..\..\..\..\target\debug\librashader_capi.dll.lib" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\..\..\librashader-capi\librashader.h">
+    <ClInclude Include="..\..\..\..\include\librashader.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\include\librashader_ld.h">
       <Filter>Header Files</Filter>
     </ClInclude>
   </ItemGroup>
   <ItemGroup>
-    <None Include="..\..\..\..\target\debug\librashader_capi.dll" />
+    <Library Include="..\..\..\..\target\debug\librashader.lib" />
   </ItemGroup>
 </Project>
\ No newline at end of file