From ff5dfc21dbcf17e78516789c36bac34e81c8785b Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Sun, 15 Mar 2026 19:39:16 +0800 Subject: [PATCH] Replace CreateTexture2D with D3D12Texture wrapper --- .../include/XCEngine/RHI/D3D12/D3D12Texture.h | 2 + engine/src/RHI/D3D12Texture.cpp | 102 ++++++++++++++++++ tests/D3D12/main.cpp | 7 +- 3 files changed, 109 insertions(+), 2 deletions(-) diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12Texture.h b/engine/include/XCEngine/RHI/D3D12/D3D12Texture.h index dfba0e07..c5d77a68 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12Texture.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12Texture.h @@ -17,6 +17,8 @@ public: bool Initialize(ID3D12Device* device, const D3D12_RESOURCE_DESC& desc, D3D12_RESOURCE_STATES initialState = D3D12_RESOURCE_STATE_COMMON); bool InitializeFromExisting(ID3D12Resource* resource); + bool InitializeFromData(ID3D12Device* device, ID3D12GraphicsCommandList* commandList, + const void* pixelData, uint32_t width, uint32_t height, DXGI_FORMAT format); void Shutdown(); ID3D12Resource* GetResource() const { return m_resource.Get(); } diff --git a/engine/src/RHI/D3D12Texture.cpp b/engine/src/RHI/D3D12Texture.cpp index 45cc03b5..7409a21b 100644 --- a/engine/src/RHI/D3D12Texture.cpp +++ b/engine/src/RHI/D3D12Texture.cpp @@ -41,6 +41,108 @@ bool D3D12Texture::InitializeFromExisting(ID3D12Resource* resource) { return true; } +bool D3D12Texture::InitializeFromData(ID3D12Device* device, ID3D12GraphicsCommandList* commandList, + const void* pixelData, uint32_t width, uint32_t height, DXGI_FORMAT format) { + + D3D12_RESOURCE_DESC textureDesc = {}; + textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + textureDesc.Alignment = 0; + textureDesc.Width = width; + textureDesc.Height = height; + textureDesc.DepthOrArraySize = 1; + textureDesc.MipLevels = 1; + textureDesc.Format = format; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + textureDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + + D3D12_HEAP_PROPERTIES heapProperties = {}; + heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT; + + HRESULT hResult = device->CreateCommittedResource( + &heapProperties, + D3D12_HEAP_FLAG_NONE, + &textureDesc, + D3D12_RESOURCE_STATE_COPY_DEST, + nullptr, + IID_PPV_ARGS(&m_resource) + ); + + if (FAILED(hResult)) { + return false; + } + + textureDesc = m_resource->GetDesc(); + UINT64 memorySizeUsed = 0; + UINT64 rowSizeInBytes = 0; + UINT rowUsed = 0; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT subresourceFootprint; + device->GetCopyableFootprints(&textureDesc, 0, 1, 0, + &subresourceFootprint, &rowUsed, &rowSizeInBytes, &memorySizeUsed); + + ID3D12Resource* tempBufferObject = nullptr; + D3D12_HEAP_PROPERTIES d3dTempHeapProperties = {}; + d3dTempHeapProperties.Type = D3D12_HEAP_TYPE_UPLOAD; + + D3D12_RESOURCE_DESC d3d12TempResourceDesc = {}; + d3d12TempResourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + d3d12TempResourceDesc.Alignment = 0; + d3d12TempResourceDesc.Width = memorySizeUsed; + d3d12TempResourceDesc.Height = 1; + d3d12TempResourceDesc.DepthOrArraySize = 1; + d3d12TempResourceDesc.MipLevels = 1; + d3d12TempResourceDesc.Format = DXGI_FORMAT_UNKNOWN; + d3d12TempResourceDesc.SampleDesc.Count = 1; + d3d12TempResourceDesc.SampleDesc.Quality = 0; + d3d12TempResourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + d3d12TempResourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + + hResult = device->CreateCommittedResource( + &d3dTempHeapProperties, + D3D12_HEAP_FLAG_NONE, + &d3d12TempResourceDesc, + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&tempBufferObject) + ); + + if (FAILED(hResult)) { + return false; + } + + BYTE* pData; + tempBufferObject->Map(0, nullptr, reinterpret_cast(&pData)); + BYTE* pDstTempBuffer = reinterpret_cast(pData + subresourceFootprint.Offset); + const BYTE* pSrcData = reinterpret_cast(pixelData); + for (UINT i = 0; i < rowUsed; i++) { + memcpy(pDstTempBuffer + subresourceFootprint.Footprint.RowPitch * i, pSrcData + rowSizeInBytes * i, rowSizeInBytes); + } + tempBufferObject->Unmap(0, nullptr); + + D3D12_TEXTURE_COPY_LOCATION dst = {}; + dst.pResource = m_resource.Get(); + dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dst.SubresourceIndex = 0; + + D3D12_TEXTURE_COPY_LOCATION src = {}; + src.pResource = tempBufferObject; + src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + src.PlacedFootprint = subresourceFootprint; + commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr); + + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition.pResource = m_resource.Get(); + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + commandList->ResourceBarrier(1, &barrier); + + return true; +} + void D3D12Texture::Shutdown() { m_resource.Reset(); } diff --git a/tests/D3D12/main.cpp b/tests/D3D12/main.cpp index ad6bf382..55353eb3 100644 --- a/tests/D3D12/main.cpp +++ b/tests/D3D12/main.cpp @@ -24,6 +24,7 @@ #include "XCEngine/RHI/D3D12/D3D12RootSignature.h" #include "XCEngine/RHI/D3D12/D3D12PipelineState.h" #include "XCEngine/RHI/D3D12/D3D12Buffer.h" +#include "XCEngine/RHI/D3D12/D3D12Texture.h" #include "XCEngine/RHI/D3D12/D3D12Screenshot.h" #include "XCEngine/Debug/Logger.h" #include "XCEngine/Debug/ConsoleLogSink.h" @@ -77,6 +78,7 @@ XCEngine::RHI::D3D12Shader gPixelShader; // Buffer objects XCEngine::RHI::D3D12Buffer gConstantBuffer; // matrices XCEngine::RHI::D3D12Buffer gMaterialBuffer; // material data +XCEngine::RHI::D3D12Texture gTexture; // earth texture // 同步对象 XCEngine::RHI::D3D12Fence gFence; @@ -828,8 +830,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine int imageWidth, imageHeight, imageChannel; stbi_uc* pixels = stbi_load("Res/Image/earth_d.jpg", &imageWidth, &imageHeight, &imageChannel, 4); Log("[DEBUG] Texture loaded: width=%d, height=%d, channels=%d, pixels=%p\n", imageWidth, imageHeight, imageChannel, pixels); - ID3D12Resource* texture = CreateTexture2D(gCommandList.GetCommandList(), pixels, - imageWidth * imageHeight * imageChannel, imageWidth, imageHeight, DXGI_FORMAT_R8G8B8A8_UNORM); + gTexture.InitializeFromData(gDevice.GetDevice(), gCommandList.GetCommandList(), pixels, + imageWidth, imageHeight, DXGI_FORMAT_R8G8B8A8_UNORM); + ID3D12Resource* texture = gTexture.GetResource(); delete[] pixels; ID3D12Device* d3dDevice = gDevice.GetDevice();