Fix RHI format conversion and add debug logging for D3D12 tests

This commit is contained in:
2026-03-25 17:30:16 +08:00
parent 9c082c72fa
commit 295459067f
10 changed files with 146 additions and 5 deletions

View File

@@ -2,6 +2,7 @@
#include <d3d12.h>
#include <string>
#include "../RHIScreenshot.h"
namespace XCEngine {
namespace RHI {
@@ -10,8 +11,11 @@ class D3D12Device;
class D3D12CommandQueue;
class D3D12Texture;
class D3D12Screenshot {
class D3D12Screenshot : public RHIScreenshot {
public:
bool Capture(RHIDevice* device, RHISwapChain* swapChain, const char* filename) override;
void Shutdown() override {}
static bool Capture(ID3D12Device* device,
ID3D12CommandQueue* commandQueue,
ID3D12Resource* renderTarget,

View File

@@ -0,0 +1,25 @@
#pragma once
#include <cstdint>
#include <string>
namespace XCEngine {
namespace RHI {
enum class RHIType : uint8_t;
class RHIDevice;
class RHISwapChain;
class RHIScreenshot {
public:
virtual ~RHIScreenshot() = default;
virtual bool Capture(RHIDevice* device, RHISwapChain* swapChain, const char* filename) = 0;
virtual void Shutdown() = 0;
static RHIScreenshot* Create(RHIType type);
};
} // namespace RHI
} // namespace XCEngine

View File

@@ -21,6 +21,10 @@ bool D3D12CommandAllocator::Initialize(ID3D12Device* device, CommandQueueType ty
if (FAILED(hResult)) {
FILE* f = fopen("D:\\Xuanchi\\Main\\XCEngine\\debug_rhi.log", "a");
if (f) { fprintf(f, "[D3D12CommandAllocator] CreateCommandAllocator failed: hr=0x%08X\n", hResult); fclose(f); }
if (hResult == DXGI_ERROR_DEVICE_REMOVED) {
FILE* f2 = fopen("D:\\Xuanchi\\Main\\XCEngine\\debug_rhi.log", "a");
if (f2) { fprintf(f2, "[D3D12CommandAllocator] Device removed reason: %d\n", device->GetDeviceRemovedReason()); fclose(f2); }
}
}
return SUCCEEDED(hResult);
}

View File

@@ -273,6 +273,12 @@ RHIBuffer* D3D12Device::CreateBuffer(const BufferDesc& desc) {
}
RHITexture* D3D12Device::CreateTexture(const TextureDesc& desc) {
OutputDebugStringA("[CreateTexture] Start\n");
{
FILE* f = fopen("D:\\Xuanchi\\Main\\XCEngine\\debug_rhi.log", "a");
if (f) { fprintf(f, "[CreateTexture] Start, m_device=%p\n", m_device.Get()); fclose(f); }
}
auto* texture = new D3D12Texture();
D3D12_RESOURCE_DESC d3d12Desc = {};
@@ -282,7 +288,7 @@ RHITexture* D3D12Device::CreateTexture(const TextureDesc& desc) {
d3d12Desc.Height = desc.height;
d3d12Desc.DepthOrArraySize = desc.depth > 0 ? desc.depth : 1;
d3d12Desc.MipLevels = desc.mipLevels > 0 ? desc.mipLevels : 1;
d3d12Desc.Format = static_cast<DXGI_FORMAT>(desc.format);
d3d12Desc.Format = ToD3D12(static_cast<Format>(desc.format));
d3d12Desc.SampleDesc.Count = desc.sampleCount > 0 ? desc.sampleCount : 1;
d3d12Desc.SampleDesc.Quality = desc.sampleQuality;
d3d12Desc.Flags = static_cast<D3D12_RESOURCE_FLAGS>(desc.flags);
@@ -294,9 +300,19 @@ RHITexture* D3D12Device::CreateTexture(const TextureDesc& desc) {
}
d3d12Desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
{
FILE* f = fopen("D:\\Xuanchi\\Main\\XCEngine\\debug_rhi.log", "a");
if (f) { fprintf(f, "[CreateTexture] Calling Initialize, device=%p, format=%d\n", m_device.Get(), (int)d3d12Desc.Format); fclose(f); }
}
if (texture->Initialize(m_device.Get(), d3d12Desc)) {
FILE* f = fopen("D:\\Xuanchi\\Main\\XCEngine\\debug_rhi.log", "a");
if (f) { fprintf(f, "[CreateTexture] Initialize succeeded\n"); fclose(f); }
return texture;
}
{
FILE* f = fopen("D:\\Xuanchi\\Main\\XCEngine\\debug_rhi.log", "a");
if (f) { fprintf(f, "[CreateTexture] Initialize FAILED\n"); fclose(f); }
}
delete texture;
return nullptr;
}
@@ -489,7 +505,7 @@ RHIResourceView* D3D12Device::CreateRenderTargetView(RHITexture* texture, const
}
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {};
rtvDesc.Format = static_cast<DXGI_FORMAT>(desc.format);
rtvDesc.Format = ToD3D12(static_cast<Format>(desc.format));
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
{
@@ -526,7 +542,7 @@ RHIResourceView* D3D12Device::CreateDepthStencilView(RHITexture* texture, const
ID3D12Resource* resource = d3d12Texture->GetResource();
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = {};
dsvDesc.Format = static_cast<DXGI_FORMAT>(desc.format);
dsvDesc.Format = ToD3D12(static_cast<Format>(desc.format));
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
auto heap = std::make_unique<D3D12DescriptorHeap>();
@@ -549,7 +565,7 @@ RHIResourceView* D3D12Device::CreateShaderResourceView(RHITexture* texture, cons
ID3D12Resource* resource = d3d12Texture->GetResource();
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.Format = static_cast<DXGI_FORMAT>(desc.format);
srvDesc.Format = ToD3D12(static_cast<Format>(desc.format));
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = desc.mipLevel > 0 ? desc.mipLevel : 1;
srvDesc.Texture2D.MostDetailedMip = 0;

View File

@@ -2,6 +2,7 @@
#include "RHI/D3D12/D3D12Device.h"
#include "RHI/D3D12/D3D12CommandQueue.h"
#include "RHI/D3D12/D3D12Texture.h"
#include "RHI/D3D12/D3D12SwapChain.h"
#include "Debug/Logger.h"
#include <d3d12.h>
#include <dxgi.h>
@@ -219,5 +220,20 @@ bool D3D12Screenshot::CopyToReadbackAndSave(ID3D12Device* device,
return true;
}
bool D3D12Screenshot::Capture(RHIDevice* device, RHISwapChain* swapChain, const char* filename) {
auto* d3d12Device = static_cast<D3D12Device*>(device);
auto* d3d12SwapChain = static_cast<D3D12SwapChain*>(swapChain);
RHITexture* tex = swapChain->GetCurrentBackBuffer();
D3D12Texture* backBuffer = static_cast<D3D12Texture*>(tex);
return CopyToReadbackAndSave(
d3d12Device->GetDevice(),
d3d12SwapChain->GetNativeCommandQueue(),
backBuffer->GetResource(),
filename,
backBuffer->GetWidth(),
backBuffer->GetHeight()
);
}
} // namespace RHI
} // namespace XCEngine

View File

@@ -11,6 +11,9 @@ D3D12Texture::~D3D12Texture() {
}
bool D3D12Texture::Initialize(ID3D12Device* device, const D3D12_RESOURCE_DESC& desc, D3D12_RESOURCE_STATES initialState) {
FILE* f = fopen("D:\\Xuanchi\\Main\\XCEngine\\debug_rhi.log", "a");
if (f) { fprintf(f, "[D3D12Texture::Initialize] Start, device=%p\n", device); fclose(f); }
D3D12_HEAP_PROPERTIES heapProperties = {};
heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
@@ -30,6 +33,8 @@ bool D3D12Texture::Initialize(ID3D12Device* device, const D3D12_RESOURCE_DESC& d
);
if (FAILED(hResult)) {
FILE* f2 = fopen("D:\\Xuanchi\\Main\\XCEngine\\debug_rhi.log", "a");
if (f2) { fprintf(f2, "[D3D12Texture::Initialize] CreateCommittedResource failed: hr=0x%08X\n", hResult); fclose(f2); }
return false;
}

View File

@@ -0,0 +1,25 @@
#include "XCEngine/RHI/RHIScreenshot.h"
#include "XCEngine/RHI/RHIEnums.h"
#include "XCEngine/RHI/D3D12/D3D12Screenshot.h"
#ifdef XCENGINE_SUPPORT_OPENGL
#include "XCEngine/RHI/OpenGL/OpenGLScreenshot.h"
#endif
namespace XCEngine {
namespace RHI {
RHIScreenshot* RHIScreenshot::Create(RHIType type) {
switch (type) {
case RHIType::D3D12:
return new D3D12Screenshot();
#ifdef XCENGINE_SUPPORT_OPENGL
case RHIType::OpenGL:
return new OpenGLScreenshot();
#endif
default:
return nullptr;
}
}
} // namespace RHI
} // namespace XCEngine

View File

@@ -8,3 +8,4 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(D3D12)
add_subdirectory(OpenGL)
add_subdirectory(unit)
add_subdirectory(integration)

View File

@@ -44,7 +44,50 @@ void RHITestFixture::SetUp() {
ASSERT_TRUE(initResult);
}
void RHITestFixture::WaitForGPU() {
if (mDevice == nullptr) {
return;
}
if (GetParam() == RHIType::D3D12) {
auto* device = static_cast<D3D12Device*>(mDevice);
CommandQueueDesc queueDesc = {};
queueDesc.queueType = static_cast<uint32_t>(CommandQueueType::Direct);
queueDesc.priority = 0;
queueDesc.nodeMask = 0;
queueDesc.flags = 0;
auto* commandQueue = device->CreateCommandQueue(queueDesc);
if (commandQueue) {
FenceDesc fenceDesc = {};
fenceDesc.initialValue = 0;
fenceDesc.flags = 0;
auto* fence = mDevice->CreateFence(fenceDesc);
if (fence) {
commandQueue->Signal(fence, 1);
fence->Wait(1);
for (int i = 0; i < 100; i++) {
if (fence->GetCompletedValue() >= 1) {
break;
}
Sleep(10);
}
fence->Shutdown();
delete fence;
}
commandQueue->Shutdown();
delete commandQueue;
}
Sleep(100);
}
}
void RHITestFixture::TearDown() {
WaitForGPU();
if (mDevice != nullptr) {
mDevice->Shutdown();
delete mDevice;

View File

@@ -16,6 +16,7 @@
#include "XCEngine/RHI/RHISampler.h"
#include "XCEngine/RHI/RHIDescriptorPool.h"
#include "XCEngine/RHI/RHIPipelineLayout.h"
#include "XCEngine/RHI/RHIEnums.h"
namespace XCEngine {
namespace RHI {
@@ -27,6 +28,7 @@ protected:
static void SetUpTestSuite();
static void TearDownTestSuite();
void WaitForGPU();
RHIDevice* GetDevice() { return mDevice; }
RHIType GetBackendType() const { return GetParam(); }