onnxruntime

Форк
0
/
ImageConverter.cpp 
149 строк · 5.8 Кб
1
// Copyright (c) Microsoft Corporation. All rights reserved.
2
// Licensed under the MIT License.
3

4
#include "lib/Api.Image/pch.h"
5
#include "inc/ImageConverter.h"
6
#include "inc/ImageConversionHelpers.h"
7
#include "inc/D3DDeviceCache.h"
8

9
using namespace Microsoft::WRL;
10

11
using namespace _winml;
12

13
void ImageConverter::SyncD3D11ToD3D12(_In_ D3DDeviceCache& device_cache, _In_ ID3D11Texture2D* pD3D11Texture) {
14
  assert(pD3D11Texture != nullptr);
15

16
  ComPtr<ID3D11Device> spTextureDevice;
17
  pD3D11Texture->GetDevice(&spTextureDevice);
18

19
  if (spTextureDevice.Get() == device_cache.GetD3D11Device()) {
20
    // If the texture is on D3DDeviceCache's device, we sync using D3DDeviceCache's fences
21
    device_cache.GPUSyncD3D11ToD3D12();
22
  } else {
23
    // Otherwise, sync using our own cached fences
24
    ComPtr<ID3D11Fence> spD3D11DeviceFence = FetchOrCreateFenceOnDevice(device_cache, spTextureDevice.Get());
25
    device_cache.SyncD3D11DeviceToConverter(spD3D11DeviceFence.Get());
26
  }
27
}
28

29
void ImageConverter::SyncD3D12ToD3D11(_In_ D3DDeviceCache& device_cache, _In_ ID3D11Texture2D* spTexture) {
30
  assert(spTexture != nullptr);
31

32
  ComPtr<ID3D11Device> spTextureDevice;
33
  spTexture->GetDevice(&spTextureDevice);
34

35
  if (spTextureDevice.Get() == device_cache.GetD3D11Device()) {
36
    // If the texture is on D3DDeviceCache's device, we sync using D3DDeviceCache's fences
37
    device_cache.GPUSyncD3D12ToD3D11();
38
  } else {
39
    // Otherwise, sync using our own cached fences
40
    ComPtr<ID3D11Fence> spD3D11DeviceFence = FetchOrCreateFenceOnDevice(device_cache, spTextureDevice.Get());
41
    device_cache.SyncConverterToD3D11Device(spD3D11DeviceFence.Get());
42
  }
43
}
44

45
ComPtr<ID3D11Fence> ImageConverter::FetchOrCreateFenceOnDevice(
46
  _In_ D3DDeviceCache& device_cache, _In_ ID3D11Device* pD3D11Device
47
) {
48
  assert(pD3D11Device != nullptr);
49

50
  ComPtr<ID3D11Fence> fence;
51
  UINT comPtrSize = static_cast<UINT>(sizeof(fence.GetAddressOf()));
52

53
  if (FAILED(pD3D11Device->GetPrivateData(device_cache.GetFenceGuid(), &comPtrSize, fence.GetAddressOf())) ||
54
      fence.Get() == nullptr) {
55
    // There's no fence on the device, so create a new one
56
    ComPtr<ID3D11Device5> spD3D11Device5;
57
    WINML_THROW_IF_FAILED(pD3D11Device->QueryInterface(IID_PPV_ARGS(&spD3D11Device5)));
58
    WINML_THROW_IF_FAILED(spD3D11Device5->OpenSharedFence(device_cache.GetConverterFenceHandle(), IID_PPV_ARGS(&fence))
59
    );
60

61
    // Store the fence on the device
62
    WINML_THROW_IF_FAILED(spD3D11Device5->SetPrivateDataInterface(device_cache.GetFenceGuid(), fence.Get()));
63
  }
64

65
  return fence;
66
}
67

68
void ImageConverter::ResetCommandList(_In_ D3DDeviceCache& device_cache) {
69
  if (!command_list_) {
70
    assert(command_allocator_ == nullptr);
71

72
    WINML_THROW_IF_FAILED(device_cache.GetD3D12Device()->CreateCommandAllocator(
73
      device_cache.GetCommandQueue()->GetDesc().Type, IID_PPV_ARGS(command_allocator_.ReleaseAndGetAddressOf())
74
    ));
75

76
    WINML_THROW_IF_FAILED(device_cache.GetD3D12Device()->CreateCommandList(
77
      0,
78
      device_cache.GetCommandQueue()->GetDesc().Type,
79
      command_allocator_.Get(),
80
      pipeline_state_.Get(),
81
      IID_PPV_ARGS(command_list_.ReleaseAndGetAddressOf())
82
    ));
83
  } else {
84
    command_list_->Reset(command_allocator_.Get(), pipeline_state_.Get());
85
  }
86
}
87

88
void ImageConverter::ResetAllocator() {
89
  WINML_THROW_IF_FAILED(command_allocator_->Reset());
90
}
91

92
ComPtr<ID3D11Texture2D> ImageConverter::CreateTextureFromUnsupportedColorFormat(
93
  const wm::IVideoFrame& videoFrame,
94
  const wgi::BitmapBounds& inputBounds,
95
  const wgi::BitmapBounds& outputBounds,
96
  wgdx::DirectXPixelFormat newFormat
97
) {
98
  assert(videoFrame != nullptr);
99

100
  // Make sure we create the new video frame on the same device. We don't want the VideoFrame pipeline to implicitly share the texture between
101
  // 2 devices since we will need to do it ourselves anyway.
102
  auto device = _winmli::GetDeviceFromDirect3DSurface(videoFrame.Direct3DSurface());
103

104
  auto spNewVideoFrame =
105
    wm::VideoFrame::CreateAsDirect3D11SurfaceBacked(newFormat, outputBounds.Width, outputBounds.Height, device);
106
  videoFrame.as<wm::IVideoFrame2>().CopyToAsync(spNewVideoFrame, inputBounds, outputBounds).get();
107

108
  using namespace Windows::Graphics::DirectX::Direct3D11;
109

110
  auto spDxgiInterfaceAccess = spNewVideoFrame.Direct3DSurface().as<IDirect3DDxgiInterfaceAccess>();
111
  ComPtr<ID3D11Texture2D> d3d11Texture;
112
  WINML_THROW_IF_FAILED(spDxgiInterfaceAccess->GetInterface(IID_PPV_ARGS(&d3d11Texture)));
113

114
  return d3d11Texture;
115
}
116

117
void ImageConverter::CopyTextureIntoTexture(
118
  _In_ ID3D11Texture2D* pTextureFrom, _In_ const wgi::BitmapBounds& inputBounds, _Inout_ ID3D11Texture2D* pTextureTo
119
) {
120
  assert(pTextureFrom != nullptr);
121
  assert(pTextureTo != nullptr);
122

123
  D3D11_TEXTURE2D_DESC textureFromDesc, textureToDesc;
124
  pTextureFrom->GetDesc(&textureFromDesc);
125
  pTextureTo->GetDesc(&textureToDesc);
126

127
  assert(inputBounds.Width <= textureFromDesc.Width && inputBounds.Width <= textureToDesc.Width);
128
  assert(inputBounds.Height <= textureFromDesc.Height && inputBounds.Height <= textureToDesc.Height);
129

130
  ComPtr<ID3D11Device> spDeviceFrom, spDeviceTo;
131
  pTextureFrom->GetDevice(&spDeviceFrom);
132
  pTextureTo->GetDevice(&spDeviceTo);
133

134
  assert(spDeviceFrom.Get() == spDeviceTo.Get());
135

136
  ComPtr<ID3D11DeviceContext> spDeviceContext;
137
  spDeviceFrom->GetImmediateContext(&spDeviceContext);
138

139
  if (textureFromDesc.Width != textureToDesc.Width || textureFromDesc.Height != textureToDesc.Height) {
140
    // We can't copy the whole resource, so we have to use the slower CopySubresource() function
141
    D3D11_BOX cropBox = CD3D11_BOX(
142
      inputBounds.X, inputBounds.Y, 0, inputBounds.X + inputBounds.Width, inputBounds.Y + inputBounds.Height, 1
143
    );
144
    spDeviceContext->CopySubresourceRegion(pTextureTo, 0, 0, 0, 0, pTextureFrom, 0, &cropBox);
145
  } else {
146
    // Use the faster CopyResource() function since both textures have the same dimensions
147
    spDeviceContext->CopyResource(pTextureTo, pTextureFrom);
148
  }
149
}
150

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.