Files
XCEngine/editor/app/Rendering/D3D12/D3D12UiTextureHost.h
2026-04-25 16:46:01 +08:00

120 lines
3.8 KiB
C++

#pragma once
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include "Rendering/Host/UiTextureHost.h"
#include <Rendering/D3D12/D3D12WindowRenderer.h>
#include <XCEngine/RHI/RHITexture.h>
#include <wincodec.h>
#include <wrl/client.h>
#include <array>
#include <cstddef>
#include <cstdint>
#include <filesystem>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
namespace XCEngine::UI::Editor::Host {
class D3D12UiTextureHost final : public Rendering::Host::UiTextureHost {
public:
bool Initialize(D3D12WindowRenderer& windowRenderer);
void Shutdown();
bool IsInitialized() const;
const std::string& GetLastError() const;
void BeginFrame(std::uint32_t frameSlot);
bool LoadTextureFromFile(
const std::filesystem::path& path,
::XCEngine::UI::UITextureHandle& outTexture,
std::string& outError) override;
bool LoadTextureFromMemory(
const std::uint8_t* data,
std::size_t size,
::XCEngine::UI::UITextureHandle& outTexture,
std::string& outError) override;
bool LoadTextureFromRgba(
const std::uint8_t* rgbaPixels,
std::uint32_t width,
std::uint32_t height,
::XCEngine::UI::UITextureHandle& outTexture,
std::string& outError) override;
bool UpdateTextureRegionRgba(
const ::XCEngine::UI::UITextureHandle& texture,
std::uint32_t dstX,
std::uint32_t dstY,
const std::uint8_t* rgbaPixels,
std::uint32_t width,
std::uint32_t height,
std::uint32_t rowPitch,
std::string& outError);
void ReleaseTexture(::XCEngine::UI::UITextureHandle& texture) override;
private:
struct TextureResource {
::XCEngine::RHI::RHITexture* texture = nullptr;
D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle = {};
D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle = {};
std::uint32_t width = 0u;
std::uint32_t height = 0u;
};
bool EnsureWicFactory(std::string& outError);
bool DecodeTextureFile(
const std::filesystem::path& path,
std::vector<std::uint8_t>& outPixels,
std::uint32_t& outWidth,
std::uint32_t& outHeight,
std::string& outError);
bool DecodeTextureMemory(
const std::uint8_t* data,
std::size_t size,
std::vector<std::uint8_t>& outPixels,
std::uint32_t& outWidth,
std::uint32_t& outHeight,
std::string& outError);
bool DecodeTextureFrame(
IWICBitmapSource& source,
std::vector<std::uint8_t>& outPixels,
std::uint32_t& outWidth,
std::uint32_t& outHeight,
std::string& outError);
bool CreateTextureResource(
const std::uint8_t* rgbaPixels,
std::uint32_t width,
std::uint32_t height,
::XCEngine::UI::UITextureHandle& outTexture,
std::string& outError);
void DestroyQueuedRetiredTextures(std::uint32_t frameSlot);
void RetireTextureResource(std::unique_ptr<TextureResource> textureResource);
TextureResource* ResolveTextureResource(const ::XCEngine::UI::UITextureHandle& texture) const;
void DestroyTextureResource(TextureResource& textureResource);
D3D12WindowRenderer* m_windowRenderer = nullptr;
Microsoft::WRL::ComPtr<IWICImagingFactory> m_wicFactory = {};
bool m_wicComInitialized = false;
std::array<
std::vector<Microsoft::WRL::ComPtr<ID3D12Resource>>,
D3D12WindowRenderer::kFrameContextCount>
m_frameUploadBuffers = {};
std::array<
std::vector<std::unique_ptr<TextureResource>>,
D3D12WindowRenderer::kFrameContextCount>
m_retiredTextures = {};
std::uint32_t m_activeFrameSlot = 0u;
bool m_hasActiveFrameSlot = false;
std::unordered_map<std::uintptr_t, std::unique_ptr<TextureResource>> m_liveTextures = {};
std::string m_lastError = {};
};
} // namespace XCEngine::UI::Editor::Host