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, + ©Srv); + 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