/* * This file is part of libplacebo. * * libplacebo is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * libplacebo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with libplacebo. If not, see . */ #ifndef LIBPLACEBO_D3D11_H_ #define LIBPLACEBO_D3D11_H_ #include #include #include #include #include PL_API_BEGIN // Structure representing the actual D3D11 device and associated GPU instance typedef const struct pl_d3d11_t { pl_gpu gpu; // The D3D11 device in use. The user is free to use this for their own // purposes, including taking a reference to the device (with AddRef) and // using it beyond the lifetime of the pl_d3d11 that created it (though if // this is done with debug enabled, it will confuse the leak checker.) ID3D11Device *device; // True if the device is using a software (WARP) adapter bool software; } *pl_d3d11; struct pl_d3d11_params { // The Direct3D 11 device to use. Optional, if NULL then libplacebo will // create its own ID3D11Device using the options below. If set, all the // options below will be ignored. ID3D11Device *device; // --- Adapter selection options // The adapter to use. This overrides adapter_luid. IDXGIAdapter *adapter; // The LUID of the adapter to use. If adapter and adapter_luid are unset, // the default adapter will be used instead. LUID adapter_luid; // Allow a software (WARP) adapter when selecting the adapter automatically. // Note that sometimes the default adapter will be a software adapter. This // is because, on Windows 8 and up, if there are no hardware adapters, // Windows will pretend the WARP adapter is the default hardware adapter. bool allow_software; // Always use a software adapter. This is mainly for testing purposes. bool force_software; // --- Device creation options // Enable the debug layer (D3D11_CREATE_DEVICE_DEBUG) // Also logs IDXGIInfoQueue messages bool debug; // Disables the use of compute shaders. Some devices/drivers perform better // without them. This may also help prevent image corruption in cases where // the driver is misbehaving. Some features may be disabled if this is set. bool no_compute; // Extra flags to pass to D3D11CreateDevice (D3D11_CREATE_DEVICE_FLAG). // libplacebo should be compatible with any flags passed here. UINT flags; // The minimum and maximum allowable feature levels for the created device. // libplacebo will attempt to create a device with the highest feature level // between min_feature_level and max_feature_level (inclusive.) If there are // no supported feature levels in this range, `pl_d3d11_create` will either // return NULL or fall back to the software adapter, depending on whether // `allow_software` is set. // // Normally there is no reason to set `max_feature_level` other than to test // if a program works at lower feature levels. // // Note that D3D_FEATURE_LEVEL_9_3 and below (known as 10level9) are highly // restrictive. These feature levels are supported on a best-effort basis. // They represent very old DirectX 9 compatible PC and laptop hardware // (2001-2007, GeForce FX, 6, 7, ATI R300-R500, GMA 950-X3000) and some // less-old mobile devices (Surface RT, Surface 2.) Basic video rendering // should work, but the full pl_gpu API will not be available and advanced // shaders will probably fail. The hardware is probably too slow for these // anyway. // // Known restrictions of 10level9 devices include: // D3D_FEATURE_LEVEL_9_3 and below: // - `pl_pass_run_params->index_buf` will not work (but `index_data` will) // - Dimensions of 3D textures must be powers of two // - Shaders cannot use gl_FragCoord // - Shaders cannot use texelFetch // D3D_FEATURE_LEVEL_9_2 and below: // - Fragment shaders have no dynamic flow control and very strict limits // on the number of constants, temporary registers and instructions. // Whether a shader meets the requirements will depend on how it's // compiled and optimized, but it's likely that only simple shaders will // work. // D3D_FEATURE_LEVEL_9_1: // - No high-bit-depth formats with PL_FMT_CAP_RENDERABLE or // PL_FMT_CAP_LINEAR // // If these restrictions are undesirable and you don't need to support // ancient hardware, set `min_feature_level` to D3D_FEATURE_LEVEL_10_0. int min_feature_level; // Defaults to D3D_FEATURE_LEVEL_9_1 if unset int max_feature_level; // Defaults to D3D_FEATURE_LEVEL_12_1 if unset // Allow up to N in-flight frames. Similar to swapchain_depth for Vulkan and // OpenGL, though with DXGI this is a device-wide setting that affects all // swapchains (except for waitable swapchains.) See the documentation for // `pl_swapchain_latency` for more information. int max_frame_latency; }; // Default/recommended parameters. Should generally be safe and efficient. #define PL_D3D11_DEFAULTS \ .allow_software = true, #define pl_d3d11_params(...) (&(struct pl_d3d11_params) { PL_D3D11_DEFAULTS __VA_ARGS__ }) PL_API extern const struct pl_d3d11_params pl_d3d11_default_params; // Creates a new Direct3D 11 device based on the given parameters, or wraps an // existing device, and initializes a new GPU instance. If params is left as // NULL, it defaults to &pl_d3d11_default_params. If an existing device is // provided in params->device, `pl_d3d11_create` will take a reference to it // that will be released in `pl_d3d11_destroy`. PL_API pl_d3d11 pl_d3d11_create(pl_log log, const struct pl_d3d11_params *params); // Release the D3D11 device. // // Note that all libplacebo objects allocated from this pl_d3d11 object (e.g. // via `d3d11->gpu` or using `pl_d3d11_create_swapchain`) *must* be explicitly // destroyed by the user before calling this. PL_API void pl_d3d11_destroy(pl_d3d11 *d3d11); // For a `pl_gpu` backed by `pl_d3d11`, this function can be used to retrieve // the underlying `pl_d3d11`. Returns NULL for any other type of `gpu`. PL_API pl_d3d11 pl_d3d11_get(pl_gpu gpu); struct pl_d3d11_swapchain_params { // The Direct3D 11 swapchain to wrap. Optional. If NULL, libplacebo will // create its own swapchain using the options below. If set, all the // swapchain creation options will be ignored. // // The provided swapchain must have been created by the same device used // by `gpu` and must not have multisampled backbuffers. IDXGISwapChain *swapchain; // --- Swapchain creation options // Initial framebuffer width and height. If both width and height are set to // 0 and window is non-NULL, the client area of the window is used instead. // For convenience, if either component would be 0, it is set to 1 instead. // This is because Windows can have 0-sized windows, but not 0-sized // swapchains. int width; int height; // The handle of the output window. In Windows 8 and up this is optional // because you can output to a CoreWindow or create a composition swapchain // instead. HWND window; // A pointer to the CoreWindow to output to. If both this and `window` are // NULL, CreateSwapChainForComposition will be used to create the swapchain. IUnknown *core_window; // If set, libplacebo will create a swapchain that uses the legacy bitblt // presentation model (with the DXGI_SWAP_EFFECT_DISCARD swap effect.) This // tends to give worse performance and frame pacing in windowed mode and it // prevents borderless fullscreen optimizations, but it might be necessary // to work around buggy drivers, especially with DXGI 1.2 in the Platform // Update for Windows 7. When unset, libplacebo will try to use the flip // presentation model and only fall back to bitblt if flip is unavailable. bool blit; // additional swapchain flags // No validation on these flags is being performed, and swapchain creation // may fail if an unsupported combination is requested. UINT flags; // --- Swapchain usage behavior options // Disable using a 10-bit swapchain format for SDR output bool disable_10bit_sdr; // Minimum number of alpha bits requested in the swapchain format. In // practice, this can be used to prefer formats with higher alpha bit depth // (e.g. rgba8/rgba16 over rgb10a2), potentially trading 2 bits per color // channel for increased alpha precision. This is a hint, if no matching // format is found, lower bit depths will be accepted. uint8_t alpha_bits; // Minimum number of color bits requested in the swapchain format. This can // be used to prefer formats with higher color bit depth. This is a hint, // if no matching format is found, lower bit depths will be accepted. uint8_t color_bits; }; #define pl_d3d11_swapchain_params(...) (&(struct pl_d3d11_swapchain_params) { __VA_ARGS__ }) // Creates a new Direct3D 11 swapchain, or wraps an existing one. If an existing // swapchain is provided in params->swapchain, `pl_d3d11_create_swapchain` will // take a reference to it that will be released in `pl_swapchain_destroy`. PL_API pl_swapchain pl_d3d11_create_swapchain(pl_d3d11 d3d11, const struct pl_d3d11_swapchain_params *params); // Takes a `pl_swapchain` created by pl_d3d11_create_swapchain and returns a // reference to the underlying IDXGISwapChain. This increments the refcount, so // call IDXGISwapChain::Release when finished with it. PL_API IDXGISwapChain *pl_d3d11_swapchain_unwrap(pl_swapchain sw); struct pl_d3d11_wrap_params { // The D3D11 texture to wrap, or a texture array containing the texture to // wrap. Must be a ID3D11Texture1D, ID3D11Texture2D or ID3D11Texture3D // created by the same device used by `gpu`, must have D3D11_USAGE_DEFAULT, // and must not be mipmapped or multisampled. ID3D11Resource *tex; // If tex is a texture array, this is the array member to use as the pl_tex. int array_slice; // If tex is a video resource (eg. DXGI_FORMAT_AYUV, DXGI_FORMAT_NV12, // DXGI_FORMAT_P010, etc.,) it can be wrapped as a pl_tex by specifying the // type and size of the shader view. For planar video formats, the plane // that is wrapped depends on the chosen format. // // If tex is not a video resource, these fields are unnecessary. The correct // format will be determined automatically. If tex is not 2D, these fields // are ignored. // // For a list of supported video formats and their corresponding view // formats and sizes, see: // https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#VideoViews DXGI_FORMAT fmt; int w; int h; }; #define pl_d3d11_wrap_params(...) (&(struct pl_d3d11_wrap_params) { __VA_ARGS__ }) // Wraps an external texture into a pl_tex abstraction. `pl_d3d11_wrap` takes a // reference to the texture, which is released when `pl_tex_destroy` is called. // // This function may fail due to incompatible formats, incompatible flags or // other reasons, in which case it will return NULL. PL_API pl_tex pl_d3d11_wrap(pl_gpu gpu, const struct pl_d3d11_wrap_params *params); PL_API_END #endif // LIBPLACEBO_D3D11_H_