examples: d3d12swapchainsink: Add uv-remap/redraw example
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9209>
This commit is contained in:
parent
c5fd61c908
commit
26227042c3
@ -23,6 +23,8 @@
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
#include <gst/d3d12/gstd3d12.h>
|
||||
#include <directx/d3dx12.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <dcomp.h>
|
||||
@ -30,14 +32,50 @@
|
||||
#include <dxgi.h>
|
||||
#include <wrl.h>
|
||||
#include <memory>
|
||||
#include <d3dcompiler.h>
|
||||
#include <string.h>
|
||||
#include "../key-handler.h"
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
static GMainLoop *loop_ = nullptr;
|
||||
static HWND hwnd_ = nullptr;
|
||||
#define VIEW_WIDTH 640
|
||||
#define VIEW_HEIGHT 480
|
||||
#define REMAP_SIZE 1024
|
||||
|
||||
static const gchar *shader_str = R"(
|
||||
RWTexture2D<float4> uvLUT : register(u0);
|
||||
|
||||
[numthreads(8, 8, 1)]
|
||||
void CSMain(uint3 DTid : SV_DispatchThreadID)
|
||||
{
|
||||
uint width, height;
|
||||
uvLUT.GetDimensions(width, height);
|
||||
|
||||
if (DTid.x >= width || DTid.y >= height)
|
||||
return;
|
||||
|
||||
float4 remapUV = float4(0.0, 0.0, 0.0, 1.0);
|
||||
remapUV.x = 1.0 - ((float) DTid.x / (float) width);
|
||||
remapUV.y = 1.0 - ((float) DTid.y / (float) height);
|
||||
|
||||
uvLUT[int2(DTid.xy)] = remapUV;
|
||||
}
|
||||
)";
|
||||
|
||||
struct GpuResource
|
||||
{
|
||||
~GpuResource ()
|
||||
{
|
||||
if (fence_val > 0 && device) {
|
||||
gst_d3d12_device_fence_wait (device, D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
fence_val);
|
||||
}
|
||||
|
||||
gst_clear_object (&device);
|
||||
}
|
||||
|
||||
ComPtr<IDCompositionDesktopDevice> dcomp_device;
|
||||
ComPtr<IDCompositionTarget> target;
|
||||
ComPtr<IDCompositionVisual2> visual;
|
||||
@ -45,11 +83,20 @@ struct GpuResource
|
||||
ComPtr<IDCompositionVisual2> swapchain_visual;
|
||||
ComPtr<ID3D11Device> device11;
|
||||
ComPtr<ID3D11DeviceContext> context11;
|
||||
GstD3D12Device *device = nullptr;
|
||||
guint64 fence_val = 0;
|
||||
ComPtr<ID3D12CommandAllocator> ca;
|
||||
ComPtr<ID3D12GraphicsCommandList> cl;
|
||||
ComPtr<ID3D12RootSignature> rs;
|
||||
ComPtr<ID3D12PipelineState> pso;
|
||||
ComPtr<ID3D12Resource> uv_remap;
|
||||
ComPtr<ID3D12DescriptorHeap> desc_heap;
|
||||
};
|
||||
|
||||
struct AppData
|
||||
{
|
||||
GstElement *pipeline = nullptr;
|
||||
GstElement *sink = nullptr;
|
||||
std::shared_ptr<GpuResource> resource;
|
||||
};
|
||||
|
||||
@ -108,15 +155,15 @@ window_proc (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
|
||||
}
|
||||
|
||||
if (SUCCEEDED (hr)) {
|
||||
if (width > 320) {
|
||||
FLOAT offset_x = ((FLOAT) (width - 320)) / 2.0;
|
||||
if (width > VIEW_WIDTH) {
|
||||
FLOAT offset_x = ((FLOAT) (width - VIEW_WIDTH)) / 2.0;
|
||||
resource->swapchain_visual->SetOffsetX (offset_x);
|
||||
} else {
|
||||
resource->swapchain_visual->SetOffsetX (0.0);
|
||||
}
|
||||
|
||||
if (height > 240) {
|
||||
FLOAT offset_y = ((FLOAT) (height - 240)) / 2.0;
|
||||
if (height > VIEW_HEIGHT) {
|
||||
FLOAT offset_y = ((FLOAT) (height - VIEW_HEIGHT)) / 2.0;
|
||||
resource->swapchain_visual->SetOffsetY (offset_y);
|
||||
} else {
|
||||
resource->swapchain_visual->SetOffsetY (0.0);
|
||||
@ -180,6 +227,262 @@ msg_cb (GIOChannel * source, GIOCondition condition, gpointer data)
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
keyboard_cb (gchar input, gboolean is_ascii, AppData * app_data)
|
||||
{
|
||||
static gboolean set_remap = FALSE;
|
||||
static GstState state = GST_STATE_PLAYING;
|
||||
|
||||
if (is_ascii) {
|
||||
switch (input) {
|
||||
case ' ':
|
||||
if (state == GST_STATE_PAUSED)
|
||||
state = GST_STATE_PLAYING;
|
||||
else
|
||||
state = GST_STATE_PAUSED;
|
||||
gst_println ("Change state to %s", gst_element_state_get_name (state));
|
||||
|
||||
gst_element_set_state (app_data->pipeline, state);
|
||||
break;
|
||||
case 'm':
|
||||
case 'M':
|
||||
set_remap = set_remap ? FALSE : TRUE;
|
||||
gst_println ("Set remap %d", set_remap);
|
||||
if (set_remap) {
|
||||
ID3D12Resource *remap[2];
|
||||
D3D12_VIEWPORT viewport[2];
|
||||
|
||||
/* top-left, draw original image */
|
||||
remap[0] = nullptr;
|
||||
viewport[0].TopLeftX = 0;
|
||||
viewport[0].TopLeftY = 0;
|
||||
viewport[0].Width = 0.5;
|
||||
viewport[0].Height = 0.5;
|
||||
|
||||
/* bottom-right, perform uv remap */
|
||||
remap[1] = app_data->resource->uv_remap.Get ();
|
||||
viewport[1].TopLeftX = 0.5;
|
||||
viewport[1].TopLeftY = 0.5;
|
||||
viewport[1].Width = 0.5;
|
||||
viewport[1].Height = 0.5;
|
||||
|
||||
g_signal_emit_by_name (app_data->sink, "uv-remap", 2, remap, viewport);
|
||||
} else {
|
||||
/* Clear remap */
|
||||
g_signal_emit_by_name (app_data->sink,
|
||||
"uv-remap", 0, nullptr, nullptr);
|
||||
}
|
||||
|
||||
/* Redraw to update view */
|
||||
if (state == GST_STATE_PAUSED)
|
||||
g_signal_emit_by_name (app_data->sink, "redraw");
|
||||
break;
|
||||
case 'q':
|
||||
g_main_loop_quit (loop_);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
creat_rs_blob (GstD3D12Device * device, ID3DBlob ** blob)
|
||||
{
|
||||
D3D12_VERSIONED_ROOT_SIGNATURE_DESC desc = { };
|
||||
CD3DX12_ROOT_PARAMETER root_params;
|
||||
CD3DX12_DESCRIPTOR_RANGE range_uav;
|
||||
|
||||
range_uav.Init (D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 1, 0);
|
||||
root_params.InitAsDescriptorTable (1, &range_uav);
|
||||
CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC::Init_1_0 (desc, 1, &root_params,
|
||||
0, nullptr,
|
||||
D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS |
|
||||
D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
|
||||
D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
|
||||
D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS);
|
||||
|
||||
ComPtr < ID3DBlob > error_blob;
|
||||
auto hr = D3DX12SerializeVersionedRootSignature (&desc,
|
||||
D3D_ROOT_SIGNATURE_VERSION_1_0, blob, &error_blob);
|
||||
if (!gst_d3d12_result (hr, device)) {
|
||||
const gchar *error_msg = nullptr;
|
||||
if (error_blob)
|
||||
error_msg = (const gchar *) error_blob->GetBufferPointer ();
|
||||
|
||||
gst_println ("Couldn't serialize rs, hr: 0x%x, error detail: %s",
|
||||
(guint) hr, GST_STR_NULL (error_msg));
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
compile_shader (GstD3D12Device * device, ID3DBlob ** blob)
|
||||
{
|
||||
ComPtr < ID3DBlob > error_blob;
|
||||
auto hr = D3DCompile (shader_str, strlen (shader_str),
|
||||
nullptr, nullptr, nullptr, "CSMain", "cs_5_0", 0, 0, blob, &error_blob);
|
||||
|
||||
if (!gst_d3d12_result (hr, device)) {
|
||||
const gchar *error_msg = nullptr;
|
||||
if (error_blob)
|
||||
error_msg = (const gchar *) error_blob->GetBufferPointer ();
|
||||
|
||||
gst_println ("Couldn't compile shader, hr: 0x%x, error detail: %s",
|
||||
(guint) hr, GST_STR_NULL (error_msg));
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
create_remap_resource (GpuResource * resource)
|
||||
{
|
||||
resource->device = gst_d3d12_device_new (0);
|
||||
if (!resource->device) {
|
||||
gst_println ("Couldn't create d3d12 device");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Prepare compute shader and resource.
|
||||
* Compute shader will write UV remap data to RGBA texture
|
||||
* (R -> U, G -> V, B -> unused, A -> mask where A < 0.5 will fill background
|
||||
* color)
|
||||
*/
|
||||
ComPtr<ID3DBlob> shader_blob;
|
||||
auto hr = compile_shader (resource->device, &shader_blob);
|
||||
if (FAILED (hr))
|
||||
return FALSE;
|
||||
|
||||
ComPtr<ID3DBlob> rs_blob;
|
||||
hr = creat_rs_blob (resource->device, &rs_blob);
|
||||
if (FAILED (hr))
|
||||
return FALSE;
|
||||
|
||||
auto device_handle = gst_d3d12_device_get_device_handle (resource->device);
|
||||
hr = device_handle->CreateRootSignature (0, rs_blob->GetBufferPointer (),
|
||||
rs_blob->GetBufferSize (), IID_PPV_ARGS (&resource->rs));
|
||||
if (!gst_d3d12_result (hr, resource->device)) {
|
||||
gst_println ("Couldn't create root signature");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
D3D12_COMPUTE_PIPELINE_STATE_DESC pso_desc = { };
|
||||
pso_desc.pRootSignature = resource->rs.Get ();
|
||||
pso_desc.CS.pShaderBytecode = shader_blob->GetBufferPointer ();
|
||||
pso_desc.CS.BytecodeLength = shader_blob->GetBufferSize ();
|
||||
hr = device_handle->CreateComputePipelineState (&pso_desc,
|
||||
IID_PPV_ARGS (&resource->pso));
|
||||
if (!gst_d3d12_result (hr, resource->device)) {
|
||||
gst_println ("Couldn't create pso");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
D3D12_HEAP_PROPERTIES heap_prop =
|
||||
CD3DX12_HEAP_PROPERTIES (D3D12_HEAP_TYPE_DEFAULT);
|
||||
D3D12_RESOURCE_DESC resource_desc =
|
||||
CD3DX12_RESOURCE_DESC::Tex2D (DXGI_FORMAT_R16G16B16A16_UNORM,
|
||||
REMAP_SIZE, REMAP_SIZE, 1, 1, 1, 0,
|
||||
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS |
|
||||
D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS);
|
||||
hr = device_handle->CreateCommittedResource (&heap_prop, D3D12_HEAP_FLAG_NONE,
|
||||
&resource_desc, D3D12_RESOURCE_STATE_COMMON, nullptr,
|
||||
IID_PPV_ARGS (&resource->uv_remap));
|
||||
if (!gst_d3d12_result (hr, resource->device)) {
|
||||
gst_println ("Couldn't create texture");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
D3D12_DESCRIPTOR_HEAP_DESC desc_heap_desc = { };
|
||||
desc_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
|
||||
desc_heap_desc.NumDescriptors = 1;
|
||||
desc_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
|
||||
hr = device_handle->CreateDescriptorHeap (&desc_heap_desc,
|
||||
IID_PPV_ARGS (&resource->desc_heap));
|
||||
if (!gst_d3d12_result (hr, resource->device)) {
|
||||
gst_println ("Couldn't create descriptor heap");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
auto cpu_handle = resource->desc_heap->GetCPUDescriptorHandleForHeapStart ();
|
||||
D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc = { };
|
||||
uav_desc.Format = DXGI_FORMAT_R16G16B16A16_UNORM;
|
||||
uav_desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
|
||||
device_handle->CreateUnorderedAccessView (resource->uv_remap.Get (),
|
||||
nullptr, &uav_desc, cpu_handle);
|
||||
|
||||
hr = device_handle->CreateCommandAllocator (D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
IID_PPV_ARGS (&resource->ca));
|
||||
if (!gst_d3d12_result (hr, resource->device)) {
|
||||
gst_println ("Couldn't create command allocator");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hr = device_handle->CreateCommandList (0, D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
resource->ca.Get (), nullptr, IID_PPV_ARGS (&resource->cl));
|
||||
if (!gst_d3d12_result (hr, resource->device)) {
|
||||
gst_println ("Couldn't create command list");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ID3D12DescriptorHeap *heaps[] = { resource->desc_heap.Get () };
|
||||
resource->cl->SetComputeRootSignature (resource->rs.Get ());
|
||||
resource->cl->SetPipelineState (resource->pso.Get ());
|
||||
resource->cl->SetDescriptorHeaps (1, heaps);
|
||||
resource->cl->SetComputeRootDescriptorTable (0,
|
||||
resource->desc_heap->GetGPUDescriptorHandleForHeapStart ());
|
||||
resource->cl->Dispatch ((REMAP_SIZE + 7) / 8, (REMAP_SIZE + 7) / 8, 1);
|
||||
hr = resource->cl->Close ();
|
||||
|
||||
if (!gst_d3d12_result (hr, resource->device)) {
|
||||
gst_println ("Couldn't close command list");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ID3D12CommandList *cmd_list[] = { resource->cl.Get () };
|
||||
hr = gst_d3d12_device_execute_command_lists (resource->device,
|
||||
D3D12_COMMAND_LIST_TYPE_DIRECT, 1, cmd_list, &resource->fence_val);
|
||||
if (!gst_d3d12_result (hr, resource->device)) {
|
||||
gst_println ("Couldn't execute command list");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
print_keyboard_help (void)
|
||||
{
|
||||
static struct
|
||||
{
|
||||
const gchar *key_desc;
|
||||
const gchar *key_help;
|
||||
} key_controls[] = {
|
||||
{"m", "Toggle remap on/off"},
|
||||
{"space", "Toggle pause/play"},
|
||||
{"q", "Quit"},
|
||||
};
|
||||
|
||||
guint i, chars_to_pad, desc_len, max_desc_len = 0;
|
||||
|
||||
gst_print ("\n%s\n", "Keyboard controls:");
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (key_controls); ++i) {
|
||||
desc_len = g_utf8_strlen (key_controls[i].key_desc, -1);
|
||||
max_desc_len = MAX (max_desc_len, desc_len);
|
||||
}
|
||||
++max_desc_len;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (key_controls); ++i) {
|
||||
chars_to_pad = max_desc_len - g_utf8_strlen (key_controls[i].key_desc, -1);
|
||||
gst_print ("\t%s", key_controls[i].key_desc);
|
||||
gst_print ("%-*s: ", chars_to_pad, "");
|
||||
gst_print ("%s\n", key_controls[i].key_help);
|
||||
}
|
||||
gst_print ("\n");
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char ** argv)
|
||||
{
|
||||
@ -220,6 +523,8 @@ main (int argc, char ** argv)
|
||||
}
|
||||
|
||||
g_object_set (app_data.pipeline, "video-sink", sink, "uri", uri, nullptr);
|
||||
/* playbin will take floating refcount */
|
||||
gst_object_ref (sink);
|
||||
} else {
|
||||
app_data.pipeline = gst_parse_launch ("d3d12testsrc ! "
|
||||
"video/x-raw(memory:D3D12Memory),format=RGBA,width=240,height=240 ! "
|
||||
@ -239,7 +544,7 @@ main (int argc, char ** argv)
|
||||
&app_data);
|
||||
|
||||
/* Set swapchain resolution and border color */
|
||||
g_signal_emit_by_name (sink, "resize", 320, 240);
|
||||
g_signal_emit_by_name (sink, "resize", VIEW_WIDTH, VIEW_HEIGHT);
|
||||
|
||||
guint64 border_color = 0;
|
||||
/* alpha */
|
||||
@ -248,6 +553,8 @@ main (int argc, char ** argv)
|
||||
border_color |= ((guint64) (G_MAXUINT16 / 2)) << 32;
|
||||
g_object_set (sink, "border-color", border_color, nullptr);
|
||||
|
||||
app_data.sink = sink;
|
||||
|
||||
/* Gets swapchain handle. This swapchain will be bound to a dcomp visual node */
|
||||
IUnknown *swapchain = nullptr;
|
||||
g_object_get (sink, "swapchain", &swapchain, nullptr);
|
||||
@ -256,10 +563,6 @@ main (int argc, char ** argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* playbin will take floating refcount */
|
||||
if (!uri)
|
||||
gst_object_unref (sink);
|
||||
|
||||
/* Creates d3d11 device to initialize dcomp device.
|
||||
* Note that d3d11 (or d2d) device will not be required if swapchain is
|
||||
* the only visual node (i.e., root node) which needs to be composed.
|
||||
@ -269,6 +572,9 @@ main (int argc, char ** argv)
|
||||
ComPtr<IDXGIFactory1> factory;
|
||||
ComPtr<IDXGIAdapter> adapter;
|
||||
|
||||
if (!create_remap_resource (resource.get ()))
|
||||
return 1;
|
||||
|
||||
hr = CreateDXGIFactory1 (IID_PPV_ARGS (&factory));
|
||||
if (FAILED (hr)) {
|
||||
gst_printerrln ("CreateDXGIFactory1 failed");
|
||||
@ -294,7 +600,7 @@ main (int argc, char ** argv)
|
||||
|
||||
/* Prepare main window */
|
||||
WNDCLASSEXW wc = { };
|
||||
RECT wr = { 0, 0, 640, 480 };
|
||||
RECT wr = { 0, 0, VIEW_WIDTH * 2, VIEW_HEIGHT * 2 };
|
||||
HINSTANCE hinstance = GetModuleHandle (nullptr);
|
||||
wc.cbSize = sizeof (WNDCLASSEXW);
|
||||
wc.lpfnWndProc = (WNDPROC) window_proc;
|
||||
@ -346,7 +652,8 @@ main (int argc, char ** argv)
|
||||
}
|
||||
|
||||
/* Create background visual, and clear color using d3d11 API */
|
||||
hr = resource->dcomp_device->CreateVirtualSurface (640, 480,
|
||||
hr = resource->dcomp_device->CreateVirtualSurface (VIEW_WIDTH * 2,
|
||||
VIEW_HEIGHT * 2,
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ALPHA_MODE_PREMULTIPLIED,
|
||||
&resource->bg_surface);
|
||||
if (FAILED (hr)) {
|
||||
@ -400,13 +707,13 @@ main (int argc, char ** argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
hr = resource->swapchain_visual->SetOffsetX (160.0);
|
||||
hr = resource->swapchain_visual->SetOffsetX (VIEW_WIDTH / 2);
|
||||
if (FAILED (hr)) {
|
||||
gst_printerrln ("SetOffsetX failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
hr = resource->swapchain_visual->SetOffsetY (120.0);
|
||||
hr = resource->swapchain_visual->SetOffsetY (VIEW_HEIGHT / 2);
|
||||
if (FAILED (hr)) {
|
||||
gst_printerrln ("SetOffsetY failed");
|
||||
return 1;
|
||||
@ -426,14 +733,19 @@ main (int argc, char ** argv)
|
||||
|
||||
app_data.resource = std::move (resource);
|
||||
|
||||
set_key_handler ((KeyInputCallback) keyboard_cb, &app_data);
|
||||
print_keyboard_help ();
|
||||
gst_element_set_state (app_data.pipeline, GST_STATE_PLAYING);
|
||||
g_main_loop_run (loop_);
|
||||
|
||||
unset_key_handler ();
|
||||
|
||||
gst_element_set_state (app_data.pipeline, GST_STATE_NULL);
|
||||
gst_bus_remove_watch (GST_ELEMENT_BUS (app_data.pipeline));
|
||||
|
||||
app_data.resource = nullptr;
|
||||
gst_object_unref (app_data.pipeline);
|
||||
gst_object_unref (app_data.sink);
|
||||
|
||||
if (hwnd_)
|
||||
DestroyWindow (hwnd_);
|
||||
|
@ -71,18 +71,20 @@ if gstd3d12_dep.found()
|
||||
dependencies: [gst_dep, gstd3d12_dep, gstvideo_dep, d3dcompile_lib, dx_headers_dep],
|
||||
install: false
|
||||
)
|
||||
endif
|
||||
endif
|
||||
|
||||
if cc.get_id() == 'msvc' and have_dcomp_h and dcomp_dep.found() and \
|
||||
have_d3d11_h and d3d11_dep.found() and have_dxgi_h and dxgi_dep.found()
|
||||
executable('d3d12swapchainsink-win32', 'd3d12swapchainsink-win32.cpp',
|
||||
c_args : gst_plugins_bad_args + ['-DGST_USE_UNSTABLE_API'],
|
||||
cpp_args : gst_plugins_bad_args + ['-DGST_USE_UNSTABLE_API'],
|
||||
include_directories : [configinc, libsinc],
|
||||
dependencies: [gst_dep, gstvideo_dep, dcomp_dep, d3d11_dep, dxgi_dep],
|
||||
install: false,
|
||||
)
|
||||
if cc.get_id() == 'msvc' and have_dcomp_h and dcomp_dep.found() and \
|
||||
have_d3d11_h and d3d11_dep.found() and have_dxgi_h and dxgi_dep.found()
|
||||
executable('d3d12swapchainsink-win32',
|
||||
['d3d12swapchainsink-win32.cpp', '../key-handler.c'],
|
||||
c_args : gst_plugins_bad_args + extra_args,
|
||||
cpp_args : gst_plugins_bad_args + extra_args,
|
||||
include_directories : [configinc, libsinc],
|
||||
dependencies: [gst_dep, gstvideo_dep, gstd3d12_dep, d3dcompile_lib,
|
||||
dx_headers_dep, dcomp_dep, d3d11_dep, dxgi_dep],
|
||||
install: false,
|
||||
)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
have_winrt_comp_headers = true
|
||||
|
Loading…
x
Reference in New Issue
Block a user