refactor(new_editor/app): reorganize host structure and add smoke test
This commit is contained in:
128
new_editor/app/Rendering/D3D12/D3D12WindowInteropResources.cpp
Normal file
128
new_editor/app/Rendering/D3D12/D3D12WindowInteropResources.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
#include "D3D12WindowInteropSupport.h"
|
||||
|
||||
namespace XCEngine::UI::Editor::Host {
|
||||
|
||||
using namespace InteropSupport;
|
||||
|
||||
void D3D12WindowInteropContext::ReleaseBackBufferTargets() {
|
||||
ClearSourceTextures();
|
||||
if (m_d2dDeviceContext != nullptr) {
|
||||
m_d2dDeviceContext->SetTarget(nullptr);
|
||||
}
|
||||
if (m_d3d11DeviceContext != nullptr) {
|
||||
m_d3d11DeviceContext->ClearState();
|
||||
}
|
||||
m_backBufferTargets.clear();
|
||||
if (m_d2dDeviceContext != nullptr) {
|
||||
D2D1_TAG firstTag = 0u;
|
||||
D2D1_TAG secondTag = 0u;
|
||||
m_d2dDeviceContext->Flush(&firstTag, &secondTag);
|
||||
}
|
||||
if (m_d3d11DeviceContext != nullptr) {
|
||||
m_d3d11DeviceContext->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
bool D3D12WindowInteropContext::RebuildBackBufferTargets() {
|
||||
m_backBufferTargets.clear();
|
||||
if (m_windowRenderer == nullptr || m_d3d11On12Device == nullptr || m_d2dDeviceContext == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::uint32_t backBufferCount = m_windowRenderer->GetBackBufferCount();
|
||||
m_backBufferTargets.resize(backBufferCount);
|
||||
for (std::uint32_t index = 0u; index < backBufferCount; ++index) {
|
||||
const ::XCEngine::RHI::D3D12Texture* backBufferTexture =
|
||||
m_windowRenderer->GetBackBufferTexture(index);
|
||||
if (backBufferTexture == nullptr || backBufferTexture->GetResource() == nullptr) {
|
||||
m_lastError = "Failed to resolve a D3D12 swap chain back buffer.";
|
||||
m_backBufferTargets.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
D3D11_RESOURCE_FLAGS resourceFlags = {};
|
||||
resourceFlags.BindFlags = D3D11_BIND_RENDER_TARGET;
|
||||
HRESULT hr = m_d3d11On12Device->CreateWrappedResource(
|
||||
backBufferTexture->GetResource(),
|
||||
&resourceFlags,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
D3D12_RESOURCE_STATE_PRESENT,
|
||||
IID_PPV_ARGS(m_backBufferTargets[index].wrappedResource.ReleaseAndGetAddressOf()));
|
||||
if (FAILED(hr) || m_backBufferTargets[index].wrappedResource == nullptr) {
|
||||
m_lastError = HrToInteropString("ID3D11On12Device::CreateWrappedResource(backbuffer)", hr);
|
||||
m_backBufferTargets.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
Microsoft::WRL::ComPtr<IDXGISurface> dxgiSurface = {};
|
||||
hr = m_backBufferTargets[index].wrappedResource.As(&dxgiSurface);
|
||||
if (FAILED(hr) || dxgiSurface == nullptr) {
|
||||
m_lastError = HrToInteropString("ID3D11Resource::QueryInterface(IDXGISurface)", hr);
|
||||
m_backBufferTargets.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
const D2D1_BITMAP_PROPERTIES1 bitmapProperties =
|
||||
BuildD2DBitmapProperties(
|
||||
backBufferTexture->GetDesc().Format,
|
||||
D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW);
|
||||
hr = m_d2dDeviceContext->CreateBitmapFromDxgiSurface(
|
||||
dxgiSurface.Get(),
|
||||
&bitmapProperties,
|
||||
m_backBufferTargets[index].targetBitmap.ReleaseAndGetAddressOf());
|
||||
if (FAILED(hr) || m_backBufferTargets[index].targetBitmap == nullptr) {
|
||||
m_lastError = HrToInteropString(
|
||||
"ID2D1DeviceContext::CreateBitmapFromDxgiSurface(backbuffer)",
|
||||
hr);
|
||||
m_backBufferTargets.clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_lastError.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3D12WindowInteropContext::HasAttachedWindowRenderer() const {
|
||||
return m_windowRenderer != nullptr &&
|
||||
m_d3d11On12Device != nullptr &&
|
||||
m_d2dDeviceContext != nullptr &&
|
||||
!m_backBufferTargets.empty();
|
||||
}
|
||||
|
||||
bool D3D12WindowInteropContext::HasBackBufferTargets() const {
|
||||
return !m_backBufferTargets.empty();
|
||||
}
|
||||
|
||||
void D3D12WindowInteropContext::BuildAcquiredResources(
|
||||
std::uint32_t backBufferIndex,
|
||||
std::vector<ID3D11Resource*>& outResources) const {
|
||||
outResources.clear();
|
||||
|
||||
ID3D11Resource* backBufferResource = GetWrappedBackBufferResource(backBufferIndex);
|
||||
if (backBufferResource != nullptr) {
|
||||
outResources.push_back(backBufferResource);
|
||||
}
|
||||
|
||||
for (const SourceTextureResource& resource : m_activeSourceTextures) {
|
||||
if (resource.wrappedResource != nullptr) {
|
||||
outResources.push_back(resource.wrappedResource.Get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ID3D11Resource* D3D12WindowInteropContext::GetWrappedBackBufferResource(std::uint32_t index) const {
|
||||
return index < m_backBufferTargets.size() ? m_backBufferTargets[index].wrappedResource.Get() : nullptr;
|
||||
}
|
||||
|
||||
ID2D1Bitmap1* D3D12WindowInteropContext::GetBackBufferTargetBitmap(std::uint32_t index) const {
|
||||
return index < m_backBufferTargets.size() ? m_backBufferTargets[index].targetBitmap.Get() : nullptr;
|
||||
}
|
||||
|
||||
std::uint32_t D3D12WindowInteropContext::GetCurrentBackBufferIndex() const {
|
||||
return m_windowRenderer != nullptr && m_windowRenderer->GetSwapChain() != nullptr
|
||||
? m_windowRenderer->GetSwapChain()->GetCurrentBackBufferIndex()
|
||||
: 0u;
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::Host
|
||||
Reference in New Issue
Block a user