#include "D3D12WindowInteropInternal.h" #include #include 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 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& 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