diff options
Diffstat (limited to 'src/include/libplacebo/d3d11.h')
-rw-r--r-- | src/include/libplacebo/d3d11.h | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/src/include/libplacebo/d3d11.h b/src/include/libplacebo/d3d11.h new file mode 100644 index 0000000..8ecba30 --- /dev/null +++ b/src/include/libplacebo/d3d11.h @@ -0,0 +1,248 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + */ + +#ifndef LIBPLACEBO_D3D11_H_ +#define LIBPLACEBO_D3D11_H_ + +#include <windows.h> +#include <d3d11.h> +#include <dxgi1_2.h> +#include <libplacebo/gpu.h> +#include <libplacebo/swapchain.h> + +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; + + // 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; +}; + +#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_ |