Files
XCEngine/new_editor/app/Rendering/D3D12/D3D12WindowInteropSourceTextures.cpp

101 lines
3.6 KiB
C++

#include "D3D12WindowInteropInternal.h"
#include <XCEngine/RHI/D3D12/D3D12Texture.h>
#include <XCEngine/RHI/RHITexture.h>
namespace XCEngine::UI::Editor::Host {
using namespace D3D12WindowInteropInternal;
bool D3D12WindowInteropContext::PrepareSourceTextures(
const ::XCEngine::UI::UIDrawData& drawData) {
ClearSourceTextures();
if (m_windowRenderer == nullptr || m_d3d11On12Device == nullptr || m_d2dDeviceContext == nullptr) {
return false;
}
std::vector<::XCEngine::UI::UITextureHandle> textureHandles = {};
CollectInteropTextureHandles(drawData, textureHandles);
m_activeSourceTextures.reserve(textureHandles.size());
for (const ::XCEngine::UI::UITextureHandle& textureHandle : textureHandles) {
auto* texture =
reinterpret_cast<::XCEngine::RHI::RHITexture*>(textureHandle.resourceHandle);
auto* nativeTexture = dynamic_cast<::XCEngine::RHI::D3D12Texture*>(texture);
if (nativeTexture == nullptr || nativeTexture->GetResource() == nullptr) {
m_lastError = "Failed to resolve a D3D12 source texture for UI composition.";
ClearSourceTextures();
return false;
}
D3D11_RESOURCE_FLAGS resourceFlags = {};
resourceFlags.BindFlags = D3D11_BIND_SHADER_RESOURCE;
SourceTextureResource resource = {};
resource.key = textureHandle.resourceHandle;
HRESULT hr = m_d3d11On12Device->CreateWrappedResource(
nativeTexture->GetResource(),
&resourceFlags,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
IID_PPV_ARGS(resource.wrappedResource.ReleaseAndGetAddressOf()));
if (FAILED(hr) || resource.wrappedResource == nullptr) {
m_lastError = HrToInteropString("ID3D11On12Device::CreateWrappedResource(source)", hr);
ClearSourceTextures();
return false;
}
Microsoft::WRL::ComPtr<IDXGISurface> dxgiSurface = {};
hr = resource.wrappedResource.As(&dxgiSurface);
if (FAILED(hr) || dxgiSurface == nullptr) {
m_lastError = HrToInteropString("ID3D11Resource::QueryInterface(IDXGISurface)", hr);
ClearSourceTextures();
return false;
}
const D2D1_BITMAP_PROPERTIES1 bitmapProperties =
BuildD2DBitmapProperties(
nativeTexture->GetDesc().Format,
D2D1_BITMAP_OPTIONS_NONE);
hr = m_d2dDeviceContext->CreateBitmapFromDxgiSurface(
dxgiSurface.Get(),
&bitmapProperties,
resource.bitmap.ReleaseAndGetAddressOf());
if (FAILED(hr) || resource.bitmap == nullptr) {
m_lastError = HrToInteropString("ID2D1DeviceContext::CreateBitmapFromDxgiSurface(source)", hr);
ClearSourceTextures();
return false;
}
m_activeBitmaps.emplace(resource.key, resource.bitmap);
m_activeSourceTextures.push_back(std::move(resource));
}
m_lastError.clear();
return true;
}
void D3D12WindowInteropContext::ClearSourceTextures() {
m_activeBitmaps.clear();
m_activeSourceTextures.clear();
}
bool D3D12WindowInteropContext::ResolveInteropBitmap(
const ::XCEngine::UI::UITextureHandle& texture,
Microsoft::WRL::ComPtr<ID2D1Bitmap>& outBitmap) const {
outBitmap.Reset();
if (!IsInteropTextureHandle(texture)) {
return false;
}
const auto found = m_activeBitmaps.find(texture.resourceHandle);
if (found == m_activeBitmaps.end() || found->second == nullptr) {
return false;
}
outBitmap = found->second;
return true;
}
} // namespace XCEngine::UI::Editor::Host