Fix RHI format conversion and add debug logging for D3D12 tests
This commit is contained in:
@@ -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,
|
||||
|
||||
25
engine/include/XCEngine/RHI/RHIScreenshot.h
Normal file
25
engine/include/XCEngine/RHI/RHIScreenshot.h
Normal 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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
25
engine/src/RHI/RHIScreenshot.cpp
Normal file
25
engine/src/RHI/RHIScreenshot.cpp
Normal 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
|
||||
@@ -8,3 +8,4 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
add_subdirectory(D3D12)
|
||||
add_subdirectory(OpenGL)
|
||||
add_subdirectory(unit)
|
||||
add_subdirectory(integration)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
Reference in New Issue
Block a user