mirror of
https://github.com/Blinue/Magpie.git
synced 2026-06-24 02:04:10 +00:00
refactor: 封装 command list 接口
This commit is contained in:
parent
66cc806b7a
commit
de3afc9876
22 changed files with 673 additions and 419 deletions
|
|
@ -1,8 +1,8 @@
|
|||
#include "pch.h"
|
||||
#include "CatmullRomDrawer.h"
|
||||
#include "CommandContext.h"
|
||||
#include "DirectXHelper.h"
|
||||
#include "GraphicsContext.h"
|
||||
#include "DescriptorHeap.h"
|
||||
#include "D3D12Context.h"
|
||||
#include "Logger.h"
|
||||
#include "shaders/CatmullRomCS.h"
|
||||
#include "shaders/CatmullRomCS_sRGB.h"
|
||||
|
|
@ -11,20 +11,18 @@
|
|||
|
||||
namespace Magpie {
|
||||
|
||||
void CatmullRomDrawer::Initialize(GraphicsContext& graphicsContext) noexcept {
|
||||
_graphicsContext = &graphicsContext;
|
||||
void CatmullRomDrawer::Initialize(D3D12Context& d3d12Context) noexcept {
|
||||
_d3d12Context = &d3d12Context;
|
||||
}
|
||||
|
||||
HRESULT CatmullRomDrawer::Draw(
|
||||
ComputeContext& computeContext,
|
||||
Size inputSize,
|
||||
Size outputSize,
|
||||
uint32_t inputSrvOffset,
|
||||
uint32_t outputUavOffset,
|
||||
bool outputSrgb
|
||||
) noexcept {
|
||||
ID3D12GraphicsCommandList* commandList = _graphicsContext->GetCommandList();
|
||||
auto& descriptorHeap = _graphicsContext->GetDescriptorHeap();
|
||||
|
||||
// 作为性能优化,输入和输出尺寸相同时原样复制
|
||||
if (inputSize == outputSize) {
|
||||
if (!_copyRootSignature) {
|
||||
|
|
@ -34,7 +32,7 @@ HRESULT CatmullRomDrawer::Draw(
|
|||
return hr;
|
||||
}
|
||||
}
|
||||
commandList->SetComputeRootSignature(_copyRootSignature.get());
|
||||
computeContext.SetRootSignature(_copyRootSignature.get());
|
||||
|
||||
if (outputSrgb) {
|
||||
if (!_copySrgbPSO) {
|
||||
|
|
@ -42,22 +40,22 @@ HRESULT CatmullRomDrawer::Draw(
|
|||
.pRootSignature = _copyRootSignature.get(),
|
||||
.CS = CD3DX12_SHADER_BYTECODE(CopyCS_sRGB, sizeof(CopyCS_sRGB))
|
||||
};
|
||||
HRESULT hr = _graphicsContext->GetDevice()->CreateComputePipelineState(
|
||||
HRESULT hr = _d3d12Context->GetDevice()->CreateComputePipelineState(
|
||||
&psoDesc, IID_PPV_ARGS(&_copySrgbPSO));
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("CreateComputePipelineState 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
commandList->SetPipelineState(_copySrgbPSO.get());
|
||||
|
||||
computeContext.SetPipelineState(_copySrgbPSO.get());
|
||||
} else {
|
||||
if (!_copyPSO) {
|
||||
D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {
|
||||
.pRootSignature = _copyRootSignature.get(),
|
||||
.CS = CD3DX12_SHADER_BYTECODE(CopyCS, sizeof(CopyCS))
|
||||
};
|
||||
HRESULT hr = _graphicsContext->GetDevice()->CreateComputePipelineState(
|
||||
HRESULT hr = _d3d12Context->GetDevice()->CreateComputePipelineState(
|
||||
&psoDesc, IID_PPV_ARGS(&_copyPSO));
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("CreateComputePipelineState 失败", hr);
|
||||
|
|
@ -65,11 +63,11 @@ HRESULT CatmullRomDrawer::Draw(
|
|||
}
|
||||
}
|
||||
|
||||
commandList->SetPipelineState(_copyPSO.get());
|
||||
computeContext.SetPipelineState(_copyPSO.get());
|
||||
}
|
||||
|
||||
commandList->SetComputeRootDescriptorTable(0, descriptorHeap.GetGpuHandle(inputSrvOffset));
|
||||
commandList->SetComputeRootDescriptorTable(1, descriptorHeap.GetGpuHandle(outputUavOffset));
|
||||
computeContext.SetRootDescriptorTable(0, inputSrvOffset);
|
||||
computeContext.SetRootDescriptorTable(1, outputUavOffset);
|
||||
} else {
|
||||
if (!_catmullRomRootSignature) {
|
||||
HRESULT hr = _InitializeCatmullRomRootSignature();
|
||||
|
|
@ -78,7 +76,7 @@ HRESULT CatmullRomDrawer::Draw(
|
|||
return hr;
|
||||
}
|
||||
}
|
||||
commandList->SetComputeRootSignature(_catmullRomRootSignature.get());
|
||||
computeContext.SetRootSignature(_catmullRomRootSignature.get());
|
||||
|
||||
if (outputSrgb) {
|
||||
if (!_catmullRomSrgbPSO) {
|
||||
|
|
@ -86,7 +84,7 @@ HRESULT CatmullRomDrawer::Draw(
|
|||
.pRootSignature = _catmullRomRootSignature.get(),
|
||||
.CS = CD3DX12_SHADER_BYTECODE(CatmullRomCS_sRGB, sizeof(CatmullRomCS_sRGB))
|
||||
};
|
||||
HRESULT hr = _graphicsContext->GetDevice()->CreateComputePipelineState(
|
||||
HRESULT hr = _d3d12Context->GetDevice()->CreateComputePipelineState(
|
||||
&psoDesc, IID_PPV_ARGS(&_catmullRomSrgbPSO));
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("CreateComputePipelineState 失败", hr);
|
||||
|
|
@ -94,14 +92,14 @@ HRESULT CatmullRomDrawer::Draw(
|
|||
}
|
||||
}
|
||||
|
||||
commandList->SetPipelineState(_catmullRomSrgbPSO.get());
|
||||
computeContext.SetPipelineState(_catmullRomSrgbPSO.get());
|
||||
} else {
|
||||
if (!_catmullRomPSO) {
|
||||
D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {
|
||||
.pRootSignature = _catmullRomRootSignature.get(),
|
||||
.CS = CD3DX12_SHADER_BYTECODE(CatmullRomCS, sizeof(CatmullRomCS))
|
||||
};
|
||||
HRESULT hr = _graphicsContext->GetDevice()->CreateComputePipelineState(
|
||||
HRESULT hr = _d3d12Context->GetDevice()->CreateComputePipelineState(
|
||||
&psoDesc, IID_PPV_ARGS(&_catmullRomPSO));
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("CreateComputePipelineState 失败", hr);
|
||||
|
|
@ -109,7 +107,7 @@ HRESULT CatmullRomDrawer::Draw(
|
|||
}
|
||||
}
|
||||
|
||||
commandList->SetPipelineState(_catmullRomPSO.get());
|
||||
computeContext.SetPipelineState(_catmullRomPSO.get());
|
||||
}
|
||||
|
||||
DirectXHelper::Constant32 constants[] = {
|
||||
|
|
@ -120,17 +118,16 @@ HRESULT CatmullRomDrawer::Draw(
|
|||
{.floatVal = 1.0f / outputSize.width},
|
||||
{.floatVal = 1.0f / outputSize.height}
|
||||
};
|
||||
commandList->SetComputeRoot32BitConstants(0, (UINT)std::size(constants), constants, 0);
|
||||
computeContext.SetRoot32BitConstants(0, (UINT)std::size(constants), constants);
|
||||
|
||||
commandList->SetComputeRootDescriptorTable(1, descriptorHeap.GetGpuHandle(inputSrvOffset));
|
||||
commandList->SetComputeRootDescriptorTable(2, descriptorHeap.GetGpuHandle(outputUavOffset));
|
||||
computeContext.SetRootDescriptorTable(1, inputSrvOffset);
|
||||
computeContext.SetRootDescriptorTable(2, outputUavOffset);
|
||||
}
|
||||
|
||||
constexpr uint32_t BLOCK_SIZE = 16;
|
||||
commandList->Dispatch(
|
||||
computeContext.Dispatch(
|
||||
(outputSize.width + BLOCK_SIZE - 1) / BLOCK_SIZE,
|
||||
(outputSize.height + BLOCK_SIZE - 1) / BLOCK_SIZE,
|
||||
1
|
||||
(outputSize.height + BLOCK_SIZE - 1) / BLOCK_SIZE
|
||||
);
|
||||
|
||||
return S_OK;
|
||||
|
|
@ -181,7 +178,7 @@ HRESULT CatmullRomDrawer::_InitializeCatmullRomRootSignature() noexcept {
|
|||
|
||||
HRESULT hr = D3DX12SerializeVersionedRootSignature(
|
||||
&rootSignatureDesc,
|
||||
_graphicsContext->GetRootSignatureVersion(),
|
||||
_d3d12Context->GetRootSignatureVersion(),
|
||||
signature.put(),
|
||||
nullptr
|
||||
);
|
||||
|
|
@ -190,7 +187,7 @@ HRESULT CatmullRomDrawer::_InitializeCatmullRomRootSignature() noexcept {
|
|||
return hr;
|
||||
}
|
||||
|
||||
hr = _graphicsContext->GetDevice()->CreateRootSignature(
|
||||
hr = _d3d12Context->GetDevice()->CreateRootSignature(
|
||||
0,
|
||||
signature->GetBufferPointer(),
|
||||
signature->GetBufferSize(),
|
||||
|
|
@ -234,7 +231,7 @@ HRESULT CatmullRomDrawer::_InitializeCopyRootSignature() noexcept {
|
|||
|
||||
HRESULT hr = D3DX12SerializeVersionedRootSignature(
|
||||
&rootSignatureDesc,
|
||||
_graphicsContext->GetRootSignatureVersion(),
|
||||
_d3d12Context->GetRootSignatureVersion(),
|
||||
signature.put(),
|
||||
nullptr
|
||||
);
|
||||
|
|
@ -243,7 +240,7 @@ HRESULT CatmullRomDrawer::_InitializeCopyRootSignature() noexcept {
|
|||
return hr;
|
||||
}
|
||||
|
||||
hr = _graphicsContext->GetDevice()->CreateRootSignature(
|
||||
hr = _d3d12Context->GetDevice()->CreateRootSignature(
|
||||
0,
|
||||
signature->GetBufferPointer(),
|
||||
signature->GetBufferSize(),
|
||||
|
|
|
|||
|
|
@ -2,13 +2,15 @@
|
|||
|
||||
namespace Magpie {
|
||||
|
||||
class GraphicsContext;
|
||||
class D3D12Context;
|
||||
class ComputeContext;
|
||||
|
||||
class CatmullRomDrawer {
|
||||
public:
|
||||
void Initialize(GraphicsContext& graphicsContext) noexcept;
|
||||
void Initialize(D3D12Context& d3d12Context) noexcept;
|
||||
|
||||
HRESULT Draw(
|
||||
ComputeContext& computeContext,
|
||||
Size inputSize,
|
||||
Size outputSize,
|
||||
uint32_t inputSrvOffset,
|
||||
|
|
@ -17,7 +19,7 @@ public:
|
|||
) noexcept;
|
||||
|
||||
private:
|
||||
GraphicsContext* _graphicsContext = nullptr;
|
||||
D3D12Context* _d3d12Context = nullptr;
|
||||
|
||||
HRESULT _InitializeCatmullRomRootSignature() noexcept;
|
||||
HRESULT _InitializeCopyRootSignature() noexcept;
|
||||
|
|
|
|||
112
src/Magpie.Core/CommandContext.cpp
Normal file
112
src/Magpie.Core/CommandContext.cpp
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
#include "pch.h"
|
||||
#include "CommandContext.h"
|
||||
#include "DescriptorHeap.h"
|
||||
|
||||
namespace Magpie {
|
||||
|
||||
void ComputeContext::SetRootSignature(ID3D12RootSignature* rootSignature) noexcept {
|
||||
_commandList->SetComputeRootSignature(rootSignature);
|
||||
}
|
||||
|
||||
void ComputeContext::SetRoot32BitConstants(
|
||||
uint32_t rootParameterIndex,
|
||||
uint32_t constantCount,
|
||||
const void* pData
|
||||
) noexcept {
|
||||
_commandList->SetComputeRoot32BitConstants(rootParameterIndex, constantCount, pData, 0);
|
||||
}
|
||||
|
||||
void ComputeContext::SetRootDescriptorTable(
|
||||
uint32_t rootParameterIndex,
|
||||
uint32_t baseDescriptorOffset
|
||||
) noexcept {
|
||||
assert(baseDescriptorOffset != std::numeric_limits<uint32_t>::max());
|
||||
|
||||
_commandList->SetComputeRootDescriptorTable(
|
||||
rootParameterIndex,
|
||||
_d3d12Context->GetDescriptorHeap().GetGpuHandle(baseDescriptorOffset)
|
||||
);
|
||||
}
|
||||
|
||||
void ComputeContext::Dispatch(
|
||||
uint32_t threadGroupCountX,
|
||||
uint32_t threadGroupCountY,
|
||||
uint32_t threadGroupCountZ
|
||||
) noexcept {
|
||||
_FlushBarriers();
|
||||
_commandList->Dispatch(threadGroupCountX, threadGroupCountY, threadGroupCountZ);
|
||||
}
|
||||
|
||||
void ComputeContext::ClearStateCache() noexcept {
|
||||
_ClearStateCache();
|
||||
}
|
||||
|
||||
void GraphicsContext::SetRootSignature(ID3D12RootSignature* rootSignature) noexcept {
|
||||
_commandList->SetGraphicsRootSignature(rootSignature);
|
||||
}
|
||||
|
||||
void GraphicsContext::SetRoot32BitConstants(
|
||||
uint32_t rootParameterIndex,
|
||||
uint32_t constantCount,
|
||||
const void* pData
|
||||
) noexcept {
|
||||
_commandList->SetGraphicsRoot32BitConstants(rootParameterIndex, constantCount, pData, 0);
|
||||
}
|
||||
|
||||
void GraphicsContext::SetRootDescriptorTable(
|
||||
uint32_t rootParameterIndex,
|
||||
uint32_t baseDescriptorOffset
|
||||
) noexcept {
|
||||
assert(baseDescriptorOffset != std::numeric_limits<uint32_t>::max());
|
||||
|
||||
// 存在 DATA_STATIC_WHILE_SET_AT_EXECUTE 时 SetGraphicsRootDescriptorTable 会检查资源状态
|
||||
if (_d3d12Context->GetRootSignatureVersion() >= D3D_ROOT_SIGNATURE_VERSION_1_1) {
|
||||
_FlushBarriers();
|
||||
}
|
||||
|
||||
_commandList->SetGraphicsRootDescriptorTable(
|
||||
rootParameterIndex,
|
||||
_d3d12Context->GetDescriptorHeap().GetGpuHandle(baseDescriptorOffset)
|
||||
);
|
||||
}
|
||||
|
||||
void GraphicsContext::IASetPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY trimitiveTopology) noexcept {
|
||||
if (trimitiveTopology != _curTrimitiveTopology) {
|
||||
_curTrimitiveTopology = trimitiveTopology;
|
||||
_commandList->IASetPrimitiveTopology(trimitiveTopology);
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsContext::RSSetViewportAndScissorRect(const D3D12_RECT& rect) noexcept {
|
||||
CD3DX12_VIEWPORT viewport((float)rect.left, (float)rect.top,
|
||||
float(rect.right - rect.left), float(rect.bottom - rect.top));
|
||||
_commandList->RSSetViewports(1, &viewport);
|
||||
|
||||
_commandList->RSSetScissorRects(1, &rect);
|
||||
}
|
||||
|
||||
void GraphicsContext::OMSetRenderTarget(uint32_t rtvDescriptorOffset) noexcept {
|
||||
assert(rtvDescriptorOffset != std::numeric_limits<uint32_t>::max());
|
||||
|
||||
if (rtvDescriptorOffset != _curRtvDescriptorOffset) {
|
||||
_curRtvDescriptorOffset = rtvDescriptorOffset;
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle =
|
||||
_d3d12Context->GetDescriptorHeap(true).GetCpuHandle(rtvDescriptorOffset);
|
||||
_commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsContext::Draw(uint32_t vertexCount) noexcept {
|
||||
_FlushBarriers();
|
||||
_commandList->DrawInstanced(vertexCount, 1, 0, 0);
|
||||
}
|
||||
|
||||
void GraphicsContext::ClearStateCache() noexcept {
|
||||
_ClearStateCache();
|
||||
|
||||
_curTrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||
_curRtvDescriptorOffset = std::numeric_limits<uint32_t>::max();
|
||||
}
|
||||
|
||||
}
|
||||
192
src/Magpie.Core/CommandContext.h
Normal file
192
src/Magpie.Core/CommandContext.h
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
#pragma once
|
||||
#include "D3D12Context.h"
|
||||
#include "SmallVector.h"
|
||||
#include "Logger.h"
|
||||
|
||||
namespace Magpie {
|
||||
|
||||
class DescriptorHeap;
|
||||
|
||||
template <typename T>
|
||||
class CommandContext {
|
||||
public:
|
||||
CommandContext() noexcept = default;
|
||||
CommandContext(const CommandContext&) = delete;
|
||||
CommandContext(CommandContext&&) = delete;
|
||||
|
||||
void Initialize(D3D12Context& d3d12Context) noexcept {
|
||||
_d3d12Context = &d3d12Context;
|
||||
_commandList = d3d12Context.GetCommandList();
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList* GetCommandList() const noexcept {
|
||||
return _commandList;
|
||||
}
|
||||
|
||||
HRESULT Execute(ID3D12CommandQueue* commandQueue) noexcept {
|
||||
_FlushBarriers();
|
||||
|
||||
HRESULT hr = _commandList->Close();
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("ID3D12GraphicsCommandList::Close 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
commandQueue->ExecuteCommandLists(1, CommandListCast(&_commandList));
|
||||
|
||||
((T*)this)->ClearStateCache();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void SetPipelineState(ID3D12PipelineState* pipelineState) noexcept {
|
||||
_commandList->SetPipelineState(pipelineState);
|
||||
}
|
||||
|
||||
void SetDescriptorHeap(ID3D12DescriptorHeap* descriptorHeap) noexcept {
|
||||
if (descriptorHeap != _curDescriptorHeap) {
|
||||
_curDescriptorHeap = descriptorHeap;
|
||||
_commandList->SetDescriptorHeaps(1, &descriptorHeap);
|
||||
}
|
||||
}
|
||||
|
||||
ID3D12DescriptorHeap* GetCurDescriptorHeap() const noexcept {
|
||||
return _curDescriptorHeap;
|
||||
}
|
||||
|
||||
void InsertTransitionBarrier(
|
||||
ID3D12Resource* resource,
|
||||
D3D12_RESOURCE_STATES stateBefore,
|
||||
D3D12_RESOURCE_STATES stateAfter
|
||||
) noexcept {
|
||||
#ifdef _DEBUG
|
||||
// 检查是否存在冗余的状态转换
|
||||
auto it = std::find_if(
|
||||
_pendingBarriers.begin(),
|
||||
_pendingBarriers.end(),
|
||||
[&](const D3D12_RESOURCE_BARRIER& barrier) {
|
||||
return barrier.Transition.pResource == resource;
|
||||
}
|
||||
);
|
||||
assert(it == _pendingBarriers.end());
|
||||
#endif
|
||||
_pendingBarriers.push_back(
|
||||
CD3DX12_RESOURCE_BARRIER::Transition(resource, stateBefore, stateAfter, 0));
|
||||
}
|
||||
|
||||
void CopyTextureRegion(
|
||||
ID3D12Resource* destResource,
|
||||
uint32_t dstX,
|
||||
uint32_t dstY,
|
||||
ID3D12Resource* srcResource,
|
||||
const D3D12_BOX* pSrcBox = nullptr
|
||||
) noexcept {
|
||||
CopyTextureRegion(
|
||||
CD3DX12_TEXTURE_COPY_LOCATION(destResource),
|
||||
dstX,
|
||||
dstY,
|
||||
CD3DX12_TEXTURE_COPY_LOCATION(srcResource),
|
||||
pSrcBox
|
||||
);
|
||||
}
|
||||
|
||||
void CopyTextureRegion(
|
||||
const CD3DX12_TEXTURE_COPY_LOCATION& dest,
|
||||
uint32_t dstX,
|
||||
uint32_t dstY,
|
||||
const CD3DX12_TEXTURE_COPY_LOCATION& src,
|
||||
const D3D12_BOX* pSrcBox = nullptr
|
||||
) noexcept {
|
||||
_FlushBarriers();
|
||||
_commandList->CopyTextureRegion(&dest, dstX, dstY, 0, &src, pSrcBox);
|
||||
}
|
||||
|
||||
void DiscardResource(ID3D12Resource* pResource) noexcept {
|
||||
_commandList->DiscardResource(pResource, nullptr);
|
||||
}
|
||||
|
||||
protected:
|
||||
void _ClearStateCache() noexcept {
|
||||
_FlushBarriers();
|
||||
|
||||
_curDescriptorHeap = nullptr;
|
||||
}
|
||||
|
||||
void _FlushBarriers() noexcept {
|
||||
if (!_pendingBarriers.empty()) {
|
||||
_commandList->ResourceBarrier(
|
||||
(UINT)_pendingBarriers.size(), _pendingBarriers.data());
|
||||
_pendingBarriers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
D3D12Context* _d3d12Context = nullptr;
|
||||
ID3D12GraphicsCommandList* _commandList = nullptr;
|
||||
|
||||
ID3D12DescriptorHeap* _curDescriptorHeap = nullptr;
|
||||
|
||||
SmallVector<D3D12_RESOURCE_BARRIER, 0> _pendingBarriers;
|
||||
};
|
||||
|
||||
class ComputeContext : public CommandContext<ComputeContext> {
|
||||
public:
|
||||
void SetRootSignature(ID3D12RootSignature* rootSignature) noexcept;
|
||||
|
||||
void SetRoot32BitConstants(
|
||||
uint32_t rootParameterIndex,
|
||||
uint32_t constantCount,
|
||||
const void* pData
|
||||
) noexcept;
|
||||
|
||||
void SetRootDescriptorTable(
|
||||
uint32_t rootParameterIndex,
|
||||
uint32_t baseDescriptorOffset
|
||||
) noexcept;
|
||||
|
||||
void Dispatch(
|
||||
uint32_t threadGroupCountX,
|
||||
uint32_t threadGroupCountY,
|
||||
uint32_t threadGroupCountZ = 1
|
||||
) noexcept;
|
||||
|
||||
void ClearStateCache() noexcept;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
class GraphicsContext : public CommandContext<GraphicsContext> {
|
||||
public:
|
||||
void SetRootSignature(ID3D12RootSignature* rootSignature) noexcept;
|
||||
|
||||
void SetRoot32BitConstants(
|
||||
uint32_t rootParameterIndex,
|
||||
uint32_t constantCount,
|
||||
const void* pData
|
||||
) noexcept;
|
||||
|
||||
void SetRootDescriptorTable(
|
||||
uint32_t rootParameterIndex,
|
||||
uint32_t baseDescriptorOffset
|
||||
) noexcept;
|
||||
|
||||
void IASetPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY trimitiveTopology) noexcept;
|
||||
|
||||
void RSSetViewportAndScissorRect(const D3D12_RECT& rect) noexcept;
|
||||
|
||||
void OMSetRenderTarget(uint32_t rtvDescriptorOffset) noexcept;
|
||||
|
||||
uint32_t OMGetRenderTarget() const noexcept {
|
||||
return _curRtvDescriptorOffset;
|
||||
}
|
||||
|
||||
void Draw(uint32_t vertexCount) noexcept;
|
||||
|
||||
void ClearStateCache() noexcept;
|
||||
|
||||
private:
|
||||
D3D12_PRIMITIVE_TOPOLOGY _curTrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||
uint32_t _curRtvDescriptorOffset = std::numeric_limits<uint32_t>::max();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
#include "pch.h"
|
||||
#include "CursorDrawer.h"
|
||||
#include "CommandContext.h"
|
||||
#include "ByteBuffer.h"
|
||||
#include "ColorHelper.h"
|
||||
#include "CursorHelper.h"
|
||||
#include "DescriptorHeap.h"
|
||||
#include "DirectXHelper.h"
|
||||
#include "GraphicsContext.h"
|
||||
#include "D3D12Context.h"
|
||||
#include "Logger.h"
|
||||
#include "ScalingWindow.h"
|
||||
#include "shaders/CursorResizerPS.h"
|
||||
|
|
@ -62,9 +63,9 @@ static DWORD GetCursorBaseSize() noexcept {
|
|||
|
||||
CursorDrawer::~CursorDrawer() noexcept {
|
||||
#ifdef _DEBUG
|
||||
if (_graphicsContext) {
|
||||
auto& descriptorHeap = _graphicsContext->GetDescriptorHeap();
|
||||
auto& rtvDescriptorHeap = _graphicsContext->GetDescriptorHeap(true);
|
||||
if (_d3d12Context) {
|
||||
auto& descriptorHeap = _d3d12Context->GetDescriptorHeap();
|
||||
auto& rtvDescriptorHeap = _d3d12Context->GetDescriptorHeap(true);
|
||||
|
||||
for (const auto& pair : _cursorInfos) {
|
||||
if (pair.second.textureSrvOffset != std::numeric_limits<uint32_t>::max()) {
|
||||
|
|
@ -92,13 +93,13 @@ CursorDrawer::~CursorDrawer() noexcept {
|
|||
}
|
||||
|
||||
bool CursorDrawer::Initialize(
|
||||
GraphicsContext& graphicsContext,
|
||||
D3D12Context& d3d12Context,
|
||||
const RECT& srcRect,
|
||||
const RECT& rendererRect,
|
||||
const RECT& destRect,
|
||||
const ColorInfo& colorInfo
|
||||
) noexcept {
|
||||
_graphicsContext = &graphicsContext;
|
||||
_d3d12Context = &d3d12Context;
|
||||
_srcSize.width = uint32_t(srcRect.right - srcRect.left);
|
||||
_srcSize.height = uint32_t(srcRect.bottom - srcRect.top);
|
||||
_rendererRect = rendererRect;
|
||||
|
|
@ -146,7 +147,7 @@ bool CursorDrawer::Initialize(
|
|||
|
||||
_cursorBaseSize = cursorBaseSize;
|
||||
// 清空已解析的光标
|
||||
_graphicsContext->WaitForGpu();
|
||||
_d3d12Context->WaitForGpu();
|
||||
_ClearCursorInfos();
|
||||
});
|
||||
});
|
||||
|
|
@ -219,10 +220,10 @@ bool CursorDrawer::CheckForRedraw(HCURSOR hCursor, POINT cursorPos) noexcept {
|
|||
}
|
||||
|
||||
HRESULT CursorDrawer::Draw(
|
||||
GraphicsContext& graphicsContext,
|
||||
uint64_t completedFenceValue,
|
||||
uint64_t nextFenceValue,
|
||||
uint32_t curFrameSrvOffset,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle,
|
||||
ID3D12Resource* backBuffer
|
||||
) noexcept {
|
||||
_ClearRetiredResources(completedFenceValue);
|
||||
|
|
@ -232,7 +233,7 @@ HRESULT CursorDrawer::Draw(
|
|||
}
|
||||
|
||||
if (!_curCursorInfo->texture) {
|
||||
HRESULT hr = _InitializeCursorTexture(*_curCursorInfo, rtvHandle);
|
||||
HRESULT hr = _InitializeCursorTexture(graphicsContext , *_curCursorInfo);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
|
@ -245,9 +246,6 @@ HRESULT CursorDrawer::Draw(
|
|||
.bottom = cursorRect.top + (LONG)_curCursorInfo->size.height
|
||||
};
|
||||
|
||||
ID3D12GraphicsCommandList* commandList = _graphicsContext->GetCommandList();
|
||||
auto& descriptorHeap = _graphicsContext->GetDescriptorHeap();
|
||||
|
||||
const bool isSrgb = _colorInfo.kind == winrt::AdvancedColorKind::StandardDynamicRange;
|
||||
|
||||
if (_curCursorInfo->type == _CursorType::Color) {
|
||||
|
|
@ -260,8 +258,8 @@ HRESULT CursorDrawer::Draw(
|
|||
}
|
||||
}
|
||||
|
||||
commandList->SetPipelineState(pso.get());
|
||||
commandList->SetGraphicsRootSignature(_colorRootSignature.get());
|
||||
graphicsContext.SetPipelineState(pso.get());
|
||||
graphicsContext.SetRootSignature(_colorRootSignature.get());
|
||||
} else {
|
||||
bool isMonochrome = _curCursorInfo->type == _CursorType::Monochrome;
|
||||
|
||||
|
|
@ -277,8 +275,8 @@ HRESULT CursorDrawer::Draw(
|
|||
}
|
||||
}
|
||||
|
||||
commandList->SetPipelineState(pso.get());
|
||||
commandList->SetGraphicsRootSignature(_maskRootSignature.get());
|
||||
graphicsContext.SetPipelineState(pso.get());
|
||||
graphicsContext.SetRootSignature(_maskRootSignature.get());
|
||||
}
|
||||
|
||||
const RECT viewportRect = {
|
||||
|
|
@ -297,12 +295,11 @@ HRESULT CursorDrawer::Draw(
|
|||
_curCursorInfo->size.width * 2 / (float)viewportSize.cx, // width
|
||||
_curCursorInfo->size.height * 2 / (float)-viewportSize.cy // height
|
||||
};
|
||||
commandList->SetGraphicsRoot32BitConstants(0, (UINT)std::size(constants), constants, 0);
|
||||
graphicsContext.SetRoot32BitConstants(0, (UINT)std::size(constants), constants);
|
||||
}
|
||||
|
||||
if (_curCursorInfo->type == _CursorType::Color) {
|
||||
commandList->SetGraphicsRootDescriptorTable(
|
||||
1, descriptorHeap.GetGpuHandle(_curCursorInfo->textureSrvOffset));
|
||||
graphicsContext.SetRootDescriptorTable(1, _curCursorInfo->textureSrvOffset);
|
||||
} else {
|
||||
DirectXHelper::Constant32 constants[] = {
|
||||
{.uintVal = _curCursorInfo->originSize.width},
|
||||
|
|
@ -315,10 +312,9 @@ HRESULT CursorDrawer::Draw(
|
|||
{.uintVal = isSrgb ? (backBuffer ? 0u : 1u) :
|
||||
std::bit_cast<uint32_t>(_colorInfo.sdrWhiteLevel)}
|
||||
};
|
||||
commandList->SetGraphicsRoot32BitConstants(1, (UINT)std::size(constants), constants, 0);
|
||||
graphicsContext.SetRoot32BitConstants(1, (UINT)std::size(constants), constants);
|
||||
|
||||
commandList->SetGraphicsRootDescriptorTable(
|
||||
2, descriptorHeap.GetGpuHandle(_curCursorInfo->textureSrvOffset));
|
||||
graphicsContext.SetRootDescriptorTable(2, _curCursorInfo->textureSrvOffset);
|
||||
|
||||
if (backBuffer) {
|
||||
// 掩码光标在叠加层上时需要从渲染目标复制光标下区域到临时纹理
|
||||
|
|
@ -337,7 +333,7 @@ HRESULT CursorDrawer::Draw(
|
|||
_tempOriginTextureSize.width = (_curCursorInfo->size.width + 31) & ~31;
|
||||
_tempOriginTextureSize.height = (_curCursorInfo->size.height + 31) & ~31;
|
||||
|
||||
ID3D12Device5* device = _graphicsContext->GetDevice();
|
||||
ID3D12Device5* device = _d3d12Context->GetDevice();
|
||||
|
||||
CD3DX12_HEAP_PROPERTIES heapProps(D3D12_HEAP_TYPE_DEFAULT);
|
||||
|
||||
|
|
@ -362,6 +358,8 @@ HRESULT CursorDrawer::Draw(
|
|||
return hr;
|
||||
}
|
||||
|
||||
auto& descriptorHeap = _d3d12Context->GetDescriptorHeap();
|
||||
|
||||
hr = descriptorHeap.Alloc(1, _tempOriginTextureSrvOffset);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("DescriptorHeap::Alloc 失败", hr);
|
||||
|
|
@ -374,15 +372,16 @@ HRESULT CursorDrawer::Draw(
|
|||
descriptorHeap.GetCpuHandle(_tempOriginTextureSrvOffset));
|
||||
}
|
||||
|
||||
{
|
||||
D3D12_RESOURCE_BARRIER barriers[] = {
|
||||
CD3DX12_RESOURCE_BARRIER::Transition(_tempOriginTexture.get(),
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST, 0),
|
||||
CD3DX12_RESOURCE_BARRIER::Transition(backBuffer,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE, 0)
|
||||
};
|
||||
commandList->ResourceBarrier((UINT)std::size(barriers), barriers);
|
||||
}
|
||||
graphicsContext.InsertTransitionBarrier(
|
||||
_tempOriginTexture.get(),
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST
|
||||
);
|
||||
graphicsContext.InsertTransitionBarrier(
|
||||
backBuffer,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
D3D12_RESOURCE_STATE_COPY_SOURCE
|
||||
);
|
||||
|
||||
{
|
||||
D3D12_BOX srcBox = {
|
||||
|
|
@ -393,51 +392,39 @@ HRESULT CursorDrawer::Draw(
|
|||
UINT(std::min(cursorRect.bottom - _rendererRect.top, viewportRect.bottom)),
|
||||
1
|
||||
};
|
||||
UINT destLeft = UINT(std::max(0l, viewportRect.left - cursorRect.left + _rendererRect.left));
|
||||
UINT destTop = UINT(std::max(0l, viewportRect.top - cursorRect.top + _rendererRect.top));
|
||||
uint32_t destLeft = uint32_t(std::max(0l,
|
||||
viewportRect.left - cursorRect.left + _rendererRect.left));
|
||||
uint32_t destTop = uint32_t(std::max(0l,
|
||||
viewportRect.top - cursorRect.top + _rendererRect.top));
|
||||
|
||||
assert(destLeft + srcBox.right - srcBox.left <= _curCursorInfo->size.width);
|
||||
assert(destTop + srcBox.bottom - srcBox.top <= _curCursorInfo->size.height);
|
||||
|
||||
CD3DX12_TEXTURE_COPY_LOCATION dest(_tempOriginTexture.get());
|
||||
CD3DX12_TEXTURE_COPY_LOCATION src(backBuffer);
|
||||
commandList->CopyTextureRegion(&dest, destLeft, destTop, 0, &src, &srcBox);
|
||||
graphicsContext.CopyTextureRegion(
|
||||
_tempOriginTexture.get(), destLeft, destTop, backBuffer, &srcBox);
|
||||
}
|
||||
|
||||
{
|
||||
D3D12_RESOURCE_BARRIER barriers[] = {
|
||||
CD3DX12_RESOURCE_BARRIER::Transition(_tempOriginTexture.get(),
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, 0),
|
||||
CD3DX12_RESOURCE_BARRIER::Transition(backBuffer,
|
||||
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET, 0)
|
||||
};
|
||||
commandList->ResourceBarrier((UINT)std::size(barriers), barriers);
|
||||
}
|
||||
graphicsContext.InsertTransitionBarrier(
|
||||
_tempOriginTexture.get(),
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE
|
||||
);
|
||||
graphicsContext.InsertTransitionBarrier(
|
||||
backBuffer,
|
||||
D3D12_RESOURCE_STATE_COPY_SOURCE,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET
|
||||
);
|
||||
|
||||
commandList->SetGraphicsRootDescriptorTable(
|
||||
3, descriptorHeap.GetGpuHandle(_tempOriginTextureSrvOffset));
|
||||
graphicsContext.SetRootDescriptorTable(3, _tempOriginTextureSrvOffset);
|
||||
} else {
|
||||
// 直接使用原始帧
|
||||
commandList->SetGraphicsRootDescriptorTable(
|
||||
3, descriptorHeap.GetGpuHandle(curFrameSrvOffset));
|
||||
graphicsContext.SetRootDescriptorTable(3, curFrameSrvOffset);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
CD3DX12_VIEWPORT viewport(
|
||||
(float)viewportRect.left,
|
||||
(float)viewportRect.top,
|
||||
(float)viewportSize.cx,
|
||||
(float)viewportSize.cy
|
||||
);
|
||||
commandList->RSSetViewports(1, &viewport);
|
||||
}
|
||||
{
|
||||
CD3DX12_RECT scissorRect(viewportRect.left, viewportRect.top, viewportRect.right, viewportRect.bottom);
|
||||
commandList->RSSetScissorRects(1, &scissorRect);
|
||||
}
|
||||
|
||||
commandList->DrawInstanced(4, 1, 0, 0);
|
||||
graphicsContext.RSSetViewportAndScissorRect(viewportRect);
|
||||
|
||||
graphicsContext.Draw(4);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
@ -468,7 +455,7 @@ void CursorDrawer::OnColorInfoChanged(const ColorInfo& colorInfo) noexcept {
|
|||
_tempOriginTextureSize = {};
|
||||
|
||||
if (_tempOriginTextureSrvOffset != std::numeric_limits<uint32_t>::max()) {
|
||||
_graphicsContext->GetDescriptorHeap().Free(_tempOriginTextureSrvOffset, 1);
|
||||
_d3d12Context->GetDescriptorHeap().Free(_tempOriginTextureSrvOffset, 1);
|
||||
_tempOriginTextureSrvOffset = std::numeric_limits<uint32_t>::max();
|
||||
}
|
||||
}
|
||||
|
|
@ -630,12 +617,6 @@ CursorDrawer::_CursorInfo* CursorDrawer::_ResolveCursor(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
HRESULT hr = _graphicsContext->GetDescriptorHeap().Alloc(1, cursorInfo.textureSrvOffset);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("DescriptorHeap::Alloc 失败", hr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &_cursorInfos.emplace(std::make_pair(hCursor, isCursorDpiAware ? monitorDpi : 0),
|
||||
std::move(cursorInfo)).first->second;
|
||||
}
|
||||
|
|
@ -915,10 +896,10 @@ bool CursorDrawer::_ResolveCursorPixels(
|
|||
}
|
||||
|
||||
HRESULT CursorDrawer::_InitializeCursorTexture(
|
||||
_CursorInfo& cursorInfo,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle
|
||||
GraphicsContext& graphicsContext,
|
||||
_CursorInfo& cursorInfo
|
||||
) noexcept {
|
||||
ID3D12Device5* device = _graphicsContext->GetDevice();
|
||||
ID3D12Device5* device = _d3d12Context->GetDevice();
|
||||
|
||||
CD3DX12_HEAP_PROPERTIES heapProps(D3D12_HEAP_TYPE_UPLOAD);
|
||||
|
||||
|
|
@ -989,23 +970,20 @@ HRESULT CursorDrawer::_InitializeCursorTexture(
|
|||
|
||||
cursorInfo.originTextureData.Clear();
|
||||
|
||||
ID3D12GraphicsCommandList* commandList = _graphicsContext->GetCommandList();
|
||||
graphicsContext.CopyTextureRegion(
|
||||
CD3DX12_TEXTURE_COPY_LOCATION(cursorInfo.originTexture.get()),
|
||||
0,
|
||||
0,
|
||||
CD3DX12_TEXTURE_COPY_LOCATION(cursorInfo.originUploadBuffer.get(), textureLayout)
|
||||
);
|
||||
|
||||
{
|
||||
CD3DX12_TEXTURE_COPY_LOCATION dest(cursorInfo.originTexture.get());
|
||||
CD3DX12_TEXTURE_COPY_LOCATION src(cursorInfo.originUploadBuffer.get(), textureLayout);
|
||||
commandList->CopyTextureRegion(&dest, 0, 0, 0, &src, nullptr);
|
||||
}
|
||||
graphicsContext.InsertTransitionBarrier(
|
||||
cursorInfo.originTexture.get(),
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE
|
||||
);
|
||||
|
||||
{
|
||||
CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(
|
||||
cursorInfo.originTexture.get(),
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
0
|
||||
);
|
||||
commandList->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
auto& descriptorHeap = _d3d12Context->GetDescriptorHeap();
|
||||
|
||||
// 单色光标和彩色掩码光标始终使用最近邻采样,无需缩放
|
||||
if (cursorInfo.type != _CursorType::Color || cursorInfo.size == cursorInfo.originSize) {
|
||||
|
|
@ -1030,10 +1008,9 @@ HRESULT CursorDrawer::_InitializeCursorTexture(
|
|||
|
||||
// 以 D3D12_HEAP_FLAG_CREATE_NOT_ZEROED 创建的资源作为渲染目标需先
|
||||
// Discard/Clear/Copy。
|
||||
commandList->DiscardResource(cursorInfo.texture.get(), nullptr);
|
||||
graphicsContext.DiscardResource(cursorInfo.texture.get());
|
||||
|
||||
auto& descriptorHeap = _graphicsContext->GetDescriptorHeap();
|
||||
auto& rtvDescriptorHeap = _graphicsContext->GetDescriptorHeap(true);
|
||||
auto& rtvDescriptorHeap = _d3d12Context->GetDescriptorHeap(true);
|
||||
|
||||
hr = descriptorHeap.Alloc(1, cursorInfo.originTextureSrvOffset);
|
||||
if (FAILED(hr)) {
|
||||
|
|
@ -1077,8 +1054,8 @@ HRESULT CursorDrawer::_InitializeCursorTexture(
|
|||
}
|
||||
}
|
||||
|
||||
commandList->SetPipelineState(_cursorResizerPSO.get());
|
||||
commandList->SetGraphicsRootSignature(_cursorResizerRootSignature.get());
|
||||
graphicsContext.SetPipelineState(_cursorResizerPSO.get());
|
||||
graphicsContext.SetRootSignature(_cursorResizerRootSignature.get());
|
||||
|
||||
{
|
||||
DirectXHelper::Constant32 constants[] = {
|
||||
|
|
@ -1087,47 +1064,39 @@ HRESULT CursorDrawer::_InitializeCursorTexture(
|
|||
{.floatVal = 1.0f / cursorInfo.originSize.width},
|
||||
{.floatVal = 1.0f / cursorInfo.originSize.height}
|
||||
};
|
||||
commandList->SetGraphicsRoot32BitConstants(0, (UINT)std::size(constants), constants, 0);
|
||||
graphicsContext.SetRoot32BitConstants(0, (UINT)std::size(constants), constants);
|
||||
}
|
||||
|
||||
commandList->SetGraphicsRootDescriptorTable(
|
||||
1, descriptorHeap.GetGpuHandle(cursorInfo.originTextureSrvOffset));
|
||||
graphicsContext.SetRootDescriptorTable(1, cursorInfo.originTextureSrvOffset);
|
||||
|
||||
{
|
||||
CD3DX12_VIEWPORT viewport(0.0f, 0.0f, (float)cursorInfo.size.width, (float)cursorInfo.size.height);
|
||||
commandList->RSSetViewports(1, &viewport);
|
||||
}
|
||||
{
|
||||
CD3DX12_RECT scissorRect(0, 0, (LONG)cursorInfo.size.width, (LONG)cursorInfo.size.height);
|
||||
commandList->RSSetScissorRects(1, &scissorRect);
|
||||
}
|
||||
graphicsContext.RSSetViewportAndScissorRect(CD3DX12_RECT(
|
||||
0, 0, (LONG)cursorInfo.size.width, (LONG)cursorInfo.size.height));
|
||||
|
||||
{
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtv =
|
||||
rtvDescriptorHeap.GetCpuHandle(_curCursorInfo->textureRtvOffset);
|
||||
commandList->OMSetRenderTargets(1, &rtv, FALSE, nullptr);
|
||||
}
|
||||
uint32_t oldRtvOffset = graphicsContext.OMGetRenderTarget();
|
||||
graphicsContext.OMSetRenderTarget(_curCursorInfo->textureRtvOffset);
|
||||
|
||||
commandList->DrawInstanced(3, 1, 0, 0);
|
||||
graphicsContext.Draw(3);
|
||||
|
||||
// 还原渲染目标
|
||||
commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr);
|
||||
graphicsContext.OMSetRenderTarget(oldRtvOffset);
|
||||
|
||||
{
|
||||
CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(
|
||||
cursorInfo.texture.get(),
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
0
|
||||
);
|
||||
commandList->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
graphicsContext.InsertTransitionBarrier(
|
||||
cursorInfo.texture.get(),
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE
|
||||
);
|
||||
}
|
||||
|
||||
hr = descriptorHeap.Alloc(1, cursorInfo.textureSrvOffset);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("DescriptorHeap::Alloc 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
CD3DX12_SHADER_RESOURCE_VIEW_DESC srvDesc =
|
||||
CD3DX12_SHADER_RESOURCE_VIEW_DESC::Tex2D(texDesc.Format, 1);
|
||||
device->CreateShaderResourceView(cursorInfo.texture.get(), &srvDesc,
|
||||
_graphicsContext->GetDescriptorHeap().GetCpuHandle(cursorInfo.textureSrvOffset));
|
||||
descriptorHeap.GetCpuHandle(cursorInfo.textureSrvOffset));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
@ -1137,8 +1106,8 @@ void CursorDrawer::_ClearCursorInfos() noexcept {
|
|||
_hCurCursor = NULL;
|
||||
_curCursorInfo = nullptr;
|
||||
|
||||
auto& descriptorHeap = _graphicsContext->GetDescriptorHeap();
|
||||
auto& rtvDescriptorHeap = _graphicsContext->GetDescriptorHeap(true);
|
||||
auto& descriptorHeap = _d3d12Context->GetDescriptorHeap();
|
||||
auto& rtvDescriptorHeap = _d3d12Context->GetDescriptorHeap(true);
|
||||
|
||||
for (const auto& pair : _cursorInfos) {
|
||||
if (pair.second.textureSrvOffset != std::numeric_limits<uint32_t>::max()) {
|
||||
|
|
@ -1193,14 +1162,14 @@ HRESULT CursorDrawer::_CreateColorPSO(
|
|||
(UINT)std::size(rootParams), rootParams, 1, &samplerDesc, D3D12_ROOT_SIGNATURE_FLAG_NONE);
|
||||
|
||||
HRESULT hr = D3DX12SerializeVersionedRootSignature(
|
||||
&rootSignatureDesc, _graphicsContext->GetRootSignatureVersion(), signature.put(), nullptr);
|
||||
&rootSignatureDesc, _d3d12Context->GetRootSignatureVersion(), signature.put(), nullptr);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("D3DX12SerializeVersionedRootSignature 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT hr = _graphicsContext->GetDevice()->CreateRootSignature(
|
||||
HRESULT hr = _d3d12Context->GetDevice()->CreateRootSignature(
|
||||
0,
|
||||
signature->GetBufferPointer(),
|
||||
signature->GetBufferSize(),
|
||||
|
|
@ -1239,7 +1208,7 @@ HRESULT CursorDrawer::_CreateColorPSO(
|
|||
.RTVFormats = { isSrgb ? DXGI_FORMAT_R8G8B8A8_UNORM : DXGI_FORMAT_R16G16B16A16_FLOAT },
|
||||
.SampleDesc = { .Count = 1 }
|
||||
};
|
||||
HRESULT hr = _graphicsContext->GetDevice()->CreateGraphicsPipelineState(
|
||||
HRESULT hr = _d3d12Context->GetDevice()->CreateGraphicsPipelineState(
|
||||
&psoDesc, IID_PPV_ARGS(&result));
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("CreateGraphicsPipelineState 失败", hr);
|
||||
|
|
@ -1300,7 +1269,7 @@ HRESULT CursorDrawer::_CreateMaskPSO(
|
|||
|
||||
HRESULT hr = D3DX12SerializeVersionedRootSignature(
|
||||
&rootSignatureDesc,
|
||||
_graphicsContext->GetRootSignatureVersion(),
|
||||
_d3d12Context->GetRootSignatureVersion(),
|
||||
signature.put(),
|
||||
nullptr
|
||||
);
|
||||
|
|
@ -1310,7 +1279,7 @@ HRESULT CursorDrawer::_CreateMaskPSO(
|
|||
}
|
||||
}
|
||||
|
||||
HRESULT hr = _graphicsContext->GetDevice()->CreateRootSignature(
|
||||
HRESULT hr = _d3d12Context->GetDevice()->CreateRootSignature(
|
||||
0,
|
||||
signature->GetBufferPointer(),
|
||||
signature->GetBufferSize(),
|
||||
|
|
@ -1358,7 +1327,7 @@ HRESULT CursorDrawer::_CreateMaskPSO(
|
|||
.RTVFormats = { isSrgb ? DXGI_FORMAT_R8G8B8A8_UNORM : DXGI_FORMAT_R16G16B16A16_FLOAT },
|
||||
.SampleDesc = { .Count = 1 }
|
||||
};
|
||||
HRESULT hr = _graphicsContext->GetDevice()->CreateGraphicsPipelineState(
|
||||
HRESULT hr = _d3d12Context->GetDevice()->CreateGraphicsPipelineState(
|
||||
&psoDesc, IID_PPV_ARGS(&result));
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("CreateGraphicsPipelineState 失败", hr);
|
||||
|
|
@ -1403,7 +1372,7 @@ HRESULT CursorDrawer::_CreateCursorResizerPSO() noexcept {
|
|||
|
||||
HRESULT hr = D3DX12SerializeVersionedRootSignature(
|
||||
&rootSignatureDesc,
|
||||
_graphicsContext->GetRootSignatureVersion(),
|
||||
_d3d12Context->GetRootSignatureVersion(),
|
||||
signature.put(),
|
||||
nullptr
|
||||
);
|
||||
|
|
@ -1413,7 +1382,7 @@ HRESULT CursorDrawer::_CreateCursorResizerPSO() noexcept {
|
|||
}
|
||||
}
|
||||
|
||||
HRESULT hr = _graphicsContext->GetDevice()->CreateRootSignature(
|
||||
HRESULT hr = _d3d12Context->GetDevice()->CreateRootSignature(
|
||||
0,
|
||||
signature->GetBufferPointer(),
|
||||
signature->GetBufferSize(),
|
||||
|
|
@ -1438,10 +1407,10 @@ HRESULT CursorDrawer::_CreateCursorResizerPSO() noexcept {
|
|||
},
|
||||
.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
|
||||
.NumRenderTargets = 1,
|
||||
.RTVFormats = DXGI_FORMAT_R16G16B16A16_FLOAT,
|
||||
.RTVFormats = { DXGI_FORMAT_R16G16B16A16_FLOAT },
|
||||
.SampleDesc = { .Count = 1 }
|
||||
};
|
||||
hr = _graphicsContext->GetDevice()->CreateGraphicsPipelineState(
|
||||
hr = _d3d12Context->GetDevice()->CreateGraphicsPipelineState(
|
||||
&psoDesc, IID_PPV_ARGS(&_cursorResizerPSO));
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("CreateGraphicsPipelineState 失败", hr);
|
||||
|
|
@ -1468,7 +1437,7 @@ void CursorDrawer::_ClearRetiredResources(uint64_t completedFenceValue) noexcept
|
|||
return;
|
||||
}
|
||||
|
||||
auto& descriptorHeap = _graphicsContext->GetDescriptorHeap();
|
||||
auto& descriptorHeap = _d3d12Context->GetDescriptorHeap();
|
||||
for (auto it1 = _retiredTempOriginTextures.begin(); it1 != it; ++it1) {
|
||||
if (it1->srvOffset != std::numeric_limits<uint32_t>::max()) {
|
||||
descriptorHeap.Free(it1->srvOffset, 1);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
namespace Magpie {
|
||||
|
||||
class D3D12Context;
|
||||
class GraphicsContext;
|
||||
|
||||
class CursorDrawer {
|
||||
|
|
@ -17,7 +18,7 @@ public:
|
|||
~CursorDrawer() noexcept;
|
||||
|
||||
bool Initialize(
|
||||
GraphicsContext& graphicsContext,
|
||||
D3D12Context& d3d12Context,
|
||||
const RECT& srcRect,
|
||||
const RECT& rendererRect,
|
||||
const RECT& destRect,
|
||||
|
|
@ -28,10 +29,10 @@ public:
|
|||
|
||||
// backBuffer 不为空表示掩码光标在叠加层上
|
||||
HRESULT Draw(
|
||||
GraphicsContext& graphicsContext,
|
||||
uint64_t completedFenceValue,
|
||||
uint64_t nextFenceValue,
|
||||
uint32_t curFrameSrvOffset,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle,
|
||||
ID3D12Resource* backBuffer = nullptr
|
||||
) noexcept;
|
||||
|
||||
|
|
@ -124,8 +125,8 @@ private:
|
|||
bool _ResolveCursorPixels(_CursorInfo& cursorInfo, HBITMAP hColorBmp, HBITMAP hMaskBmp) const noexcept;
|
||||
|
||||
HRESULT _InitializeCursorTexture(
|
||||
_CursorInfo& cursorInfo,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle
|
||||
GraphicsContext& graphicsContext,
|
||||
_CursorInfo& cursorInfo
|
||||
) noexcept;
|
||||
|
||||
// 只能在同步 GPU 后调用
|
||||
|
|
@ -143,7 +144,7 @@ private:
|
|||
|
||||
void _ClearRetiredResources(uint64_t completedFenceValue) noexcept;
|
||||
|
||||
GraphicsContext* _graphicsContext = nullptr;
|
||||
D3D12Context* _d3d12Context = nullptr;
|
||||
Size _srcSize{};
|
||||
RECT _rendererRect{};
|
||||
RECT _destRect{};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "pch.h"
|
||||
#include "GraphicsContext.h"
|
||||
#include "D3D12Context.h"
|
||||
#include "DebugInfo.h"
|
||||
#include "Logger.h"
|
||||
#include "DirectXHelper.h"
|
||||
|
|
@ -8,12 +8,7 @@
|
|||
|
||||
namespace Magpie {
|
||||
|
||||
// 如果描述符大小为 32 字节,描述符堆消耗 2MiB 显存
|
||||
static uint32_t CSU_HEAP_CAPACITY = 65536;
|
||||
// 目前只有渲染到后缓冲和缩放光标时需要 RTV
|
||||
static uint32_t RTV_HEAP_CAPACITY = 1024;
|
||||
|
||||
bool GraphicsContext::Initialize(
|
||||
bool D3D12Context::Initialize(
|
||||
const GraphicsCardId& graphicsCardId,
|
||||
uint32_t maxInFlightFrameCount,
|
||||
D3D12_COMMAND_QUEUE_PRIORITY priority,
|
||||
|
|
@ -86,29 +81,17 @@ bool GraphicsContext::Initialize(
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!_csuDescriptorHeap->Initialize(
|
||||
_device.get(), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, CSU_HEAP_CAPACITY)) {
|
||||
Logger::Get().Error("DescriptorHeap::Initialize 失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_rtvDescriptorHeap->Initialize(
|
||||
_device.get(), D3D12_DESCRIPTOR_HEAP_TYPE_RTV, RTV_HEAP_CAPACITY)) {
|
||||
Logger::Get().Error("DescriptorHeap::Initialize 失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GraphicsContext::CopyDevice(const GraphicsContext& other) {
|
||||
void D3D12Context::CopyDevice(const D3D12Context& other) {
|
||||
_csuDescriptorHeap = other._csuDescriptorHeap;
|
||||
_rtvDescriptorHeap = other._rtvDescriptorHeap;
|
||||
_device = other._device;
|
||||
_rootSignatureVersion = other._rootSignatureVersion;
|
||||
}
|
||||
|
||||
bool GraphicsContext::InitializeAfterCopyDevice(
|
||||
bool D3D12Context::InitializeAfterCopyDevice(
|
||||
uint32_t maxInFlightFrameCount,
|
||||
D3D12_COMMAND_QUEUE_PRIORITY priority,
|
||||
D3D12_COMMAND_LIST_TYPE commandListType,
|
||||
|
|
@ -133,7 +116,7 @@ bool GraphicsContext::InitializeAfterCopyDevice(
|
|||
return true;
|
||||
}
|
||||
|
||||
IDXGIFactory7* GraphicsContext::GetDXGIFactoryForEnumingAdapters() noexcept {
|
||||
IDXGIFactory7* D3D12Context::GetDXGIFactoryForEnumingAdapters() noexcept {
|
||||
if (!_dxgiFactory->IsCurrent()) {
|
||||
HRESULT hr = _CreateDXGIFactory();
|
||||
if (FAILED(hr)) {
|
||||
|
|
@ -145,12 +128,12 @@ IDXGIFactory7* GraphicsContext::GetDXGIFactoryForEnumingAdapters() noexcept {
|
|||
return _dxgiFactory.get();
|
||||
}
|
||||
|
||||
HRESULT GraphicsContext::Signal(uint64_t& fenceValue) noexcept {
|
||||
HRESULT D3D12Context::Signal(uint64_t& fenceValue) noexcept {
|
||||
fenceValue = ++_curFenceValue;
|
||||
return _commandQueue->Signal(_fence.get(), _curFenceValue);
|
||||
}
|
||||
|
||||
HRESULT GraphicsContext::WaitForFenceValue(uint64_t fenceValue) noexcept {
|
||||
HRESULT D3D12Context::WaitForFenceValue(uint64_t fenceValue) noexcept {
|
||||
if (_fence->GetCompletedValue() >= fenceValue) {
|
||||
return S_OK;
|
||||
} else {
|
||||
|
|
@ -158,7 +141,7 @@ HRESULT GraphicsContext::WaitForFenceValue(uint64_t fenceValue) noexcept {
|
|||
}
|
||||
}
|
||||
|
||||
HRESULT GraphicsContext::WaitForGpu() noexcept {
|
||||
HRESULT D3D12Context::WaitForGpu() noexcept {
|
||||
HRESULT hr = _commandQueue->Signal(_fence.get(), ++_curFenceValue);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("ID3D12CommandQueue::Signal 失败", hr);
|
||||
|
|
@ -168,7 +151,7 @@ HRESULT GraphicsContext::WaitForGpu() noexcept {
|
|||
return WaitForFenceValue(_curFenceValue);
|
||||
}
|
||||
|
||||
HRESULT GraphicsContext::WaitForCommandQueue(ID3D12CommandQueue* commandQueue) noexcept {
|
||||
HRESULT D3D12Context::WaitForCommandQueue(ID3D12CommandQueue* commandQueue) noexcept {
|
||||
HRESULT hr = commandQueue->Signal(_fence.get(), ++_curFenceValue);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("ID3D12CommandQueue::Signal 失败", hr);
|
||||
|
|
@ -184,7 +167,7 @@ HRESULT GraphicsContext::WaitForCommandQueue(ID3D12CommandQueue* commandQueue) n
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT GraphicsContext::BeginFrame(uint32_t& curFrameIndex, ID3D12PipelineState* initialState) noexcept {
|
||||
HRESULT D3D12Context::BeginFrame(uint32_t& curFrameIndex, ID3D12PipelineState* initialState) noexcept {
|
||||
if (!_frameFenceValues.empty()) {
|
||||
HRESULT hr = WaitForFenceValue(_frameFenceValues[_curFrameIndex]);
|
||||
if (FAILED(hr)) {
|
||||
|
|
@ -209,7 +192,7 @@ HRESULT GraphicsContext::BeginFrame(uint32_t& curFrameIndex, ID3D12PipelineState
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT GraphicsContext::EndFrame() noexcept {
|
||||
HRESULT D3D12Context::EndFrame() noexcept {
|
||||
if (!_frameFenceValues.empty()) {
|
||||
HRESULT hr = Signal(_frameFenceValues[_curFrameIndex]);
|
||||
if (FAILED(hr)) {
|
||||
|
|
@ -222,7 +205,7 @@ HRESULT GraphicsContext::EndFrame() noexcept {
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT GraphicsContext::_CreateDXGIFactory() noexcept {
|
||||
HRESULT D3D12Context::_CreateDXGIFactory() noexcept {
|
||||
UINT flags = 0;
|
||||
#ifdef _DEBUG
|
||||
flags |= DXGI_CREATE_FACTORY_DEBUG;
|
||||
|
|
@ -234,7 +217,7 @@ HRESULT GraphicsContext::_CreateDXGIFactory() noexcept {
|
|||
return hr;
|
||||
}
|
||||
|
||||
bool GraphicsContext::_InitializeDeviceResources(
|
||||
bool D3D12Context::_InitializeDeviceResources(
|
||||
uint32_t maxInFlightFrameCount,
|
||||
D3D12_COMMAND_QUEUE_PRIORITY priority,
|
||||
D3D12_COMMAND_LIST_TYPE commandListType,
|
||||
|
|
@ -283,7 +266,7 @@ bool GraphicsContext::_InitializeDeviceResources(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GraphicsContext::_CreateAdapterAndDevice(const GraphicsCardId& graphicsCardId) noexcept {
|
||||
bool D3D12Context::_CreateAdapterAndDevice(const GraphicsCardId& graphicsCardId) noexcept {
|
||||
winrt::com_ptr<IDXGIAdapter1> adapter;
|
||||
|
||||
#ifdef MP_DEBUG_INFO
|
||||
|
|
@ -387,7 +370,7 @@ bool GraphicsContext::_CreateAdapterAndDevice(const GraphicsCardId& graphicsCard
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GraphicsContext::_TryCreateD3DDevice(const winrt::com_ptr<IDXGIAdapter1>& adapter, const DXGI_ADAPTER_DESC1& adapterDesc) noexcept {
|
||||
bool D3D12Context::_TryCreateD3DDevice(const winrt::com_ptr<IDXGIAdapter1>& adapter, const DXGI_ADAPTER_DESC1& adapterDesc) noexcept {
|
||||
HRESULT hr = D3D12CreateDevice(adapter.get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&_device));
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("D3D12CreateDevice 失败", hr);
|
||||
|
|
@ -447,7 +430,7 @@ bool GraphicsContext::_TryCreateD3DDevice(const winrt::com_ptr<IDXGIAdapter1>& a
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GraphicsContext::_CreateAdapterFromDevice() noexcept {
|
||||
bool D3D12Context::_CreateAdapterFromDevice() noexcept {
|
||||
const LUID adapterLuid = _device->GetAdapterLuid();
|
||||
|
||||
winrt::com_ptr<IDXGIAdapter1> adapter;
|
||||
|
|
@ -5,11 +5,11 @@ namespace Magpie {
|
|||
|
||||
class DescriptorHeap;
|
||||
|
||||
class GraphicsContext {
|
||||
class D3D12Context {
|
||||
public:
|
||||
GraphicsContext() = default;
|
||||
GraphicsContext(const GraphicsContext&) = delete;
|
||||
GraphicsContext(GraphicsContext&&) = delete;
|
||||
D3D12Context() = default;
|
||||
D3D12Context(const D3D12Context&) = delete;
|
||||
D3D12Context(D3D12Context&&) = delete;
|
||||
|
||||
bool Initialize(
|
||||
const GraphicsCardId& graphicsCardId,
|
||||
|
|
@ -21,7 +21,7 @@ public:
|
|||
bool disableFrameFenceTracking = false
|
||||
) noexcept;
|
||||
|
||||
void CopyDevice(const GraphicsContext& other);
|
||||
void CopyDevice(const D3D12Context& other);
|
||||
|
||||
bool InitializeAfterCopyDevice(
|
||||
uint32_t maxInFlightFrameCount,
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
#include "pch.h"
|
||||
#include "EffectsDrawer.h"
|
||||
#include "CatmullRomDrawer.h"
|
||||
#include "GraphicsContext.h"
|
||||
#include "CommandContext.h"
|
||||
#include "D3D12Context.h"
|
||||
#include "Logger.h"
|
||||
#include "ScalingWindow.h"
|
||||
#include "StrHelper.h"
|
||||
|
|
@ -9,16 +10,16 @@
|
|||
namespace Magpie {
|
||||
|
||||
bool EffectsDrawer::Initialize(
|
||||
GraphicsContext& graphicsContext,
|
||||
D3D12Context& d3d12Context,
|
||||
const ColorInfo& colorInfo,
|
||||
Size inputSize,
|
||||
Size rendererSize
|
||||
) noexcept {
|
||||
_graphicsContext = &graphicsContext;
|
||||
_d3d12Context = &d3d12Context;
|
||||
_isScRGB = colorInfo.kind != winrt::AdvancedColorKind::StandardDynamicRange;
|
||||
_inputSize = inputSize;
|
||||
|
||||
ID3D12Device5* device = graphicsContext.GetDevice();
|
||||
ID3D12Device5* device = d3d12Context.GetDevice();
|
||||
|
||||
// 检查半精度浮点支持
|
||||
{
|
||||
|
|
@ -44,7 +45,7 @@ bool EffectsDrawer::Initialize(
|
|||
}
|
||||
|
||||
_catmullRomDrawer.emplace();
|
||||
_catmullRomDrawer->Initialize(graphicsContext);
|
||||
_catmullRomDrawer->Initialize(d3d12Context);
|
||||
|
||||
{
|
||||
// 每帧两个时间戳
|
||||
|
|
@ -76,7 +77,7 @@ bool EffectsDrawer::Initialize(
|
|||
return false;
|
||||
}
|
||||
|
||||
hr = graphicsContext.GetCommandQueue()->GetTimestampFrequency(&_timestampFrequency);
|
||||
hr = d3d12Context.GetCommandQueue()->GetTimestampFrequency(&_timestampFrequency);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("ID3D12CommandQueue::GetTimestampFrequency 失败", hr);
|
||||
return false;
|
||||
|
|
@ -87,39 +88,39 @@ bool EffectsDrawer::Initialize(
|
|||
}
|
||||
|
||||
HRESULT EffectsDrawer::Draw(
|
||||
uint32_t frameIndex,
|
||||
ComputeContext& computeContext,
|
||||
uint32_t /*frameIndex*/,
|
||||
ID3D12Resource* /*inputResource*/,
|
||||
ID3D12Resource* /*outputResource*/,
|
||||
uint32_t inputSrvOffset,
|
||||
uint32_t outputUavOffset
|
||||
) noexcept {
|
||||
// 获取渲染时间
|
||||
const uint32_t queryHeapIndex = 2 * frameIndex;
|
||||
{
|
||||
CD3DX12_RANGE range(queryHeapIndex * sizeof(UINT64), (queryHeapIndex + 2) * sizeof(UINT64));
|
||||
// const uint32_t queryHeapIndex = 2 * frameIndex;
|
||||
// {
|
||||
// CD3DX12_RANGE range(queryHeapIndex * sizeof(UINT64), (queryHeapIndex + 2) * sizeof(UINT64));
|
||||
|
||||
// void* pData;
|
||||
// HRESULT hr = _queryResultBuffer->Map(0, nullptr, &pData);
|
||||
// if (FAILED(hr)) {
|
||||
// Logger::Get().ComError("ID3D12Resource::Map 失败", hr);
|
||||
// return hr;
|
||||
// }
|
||||
|
||||
// UINT64* timestampes = (UINT64*)pData + queryHeapIndex;
|
||||
|
||||
// range = {};
|
||||
// _queryResultBuffer->Unmap(0, &range);
|
||||
// }
|
||||
|
||||
void* pData;
|
||||
HRESULT hr = _queryResultBuffer->Map(0, nullptr, &pData);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("ID3D12Resource::Map 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
//commandList->EndQuery(_queryHeap.get(), D3D12_QUERY_TYPE_TIMESTAMP, queryHeapIndex);
|
||||
|
||||
// UINT64* timestampes = (UINT64*)pData + queryHeapIndex;
|
||||
_catmullRomDrawer->Draw(
|
||||
computeContext, _inputSize, _outputSize, inputSrvOffset, outputUavOffset, false);
|
||||
|
||||
range = {};
|
||||
_queryResultBuffer->Unmap(0, &range);
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList* commandList = _graphicsContext->GetCommandList();
|
||||
|
||||
commandList->EndQuery(_queryHeap.get(), D3D12_QUERY_TYPE_TIMESTAMP, queryHeapIndex);
|
||||
|
||||
_catmullRomDrawer->Draw(_inputSize, _outputSize, inputSrvOffset, outputUavOffset, false);
|
||||
|
||||
commandList->EndQuery(_queryHeap.get(), D3D12_QUERY_TYPE_TIMESTAMP, queryHeapIndex + 1);
|
||||
commandList->ResolveQueryData(_queryHeap.get(), D3D12_QUERY_TYPE_TIMESTAMP, queryHeapIndex, 2,
|
||||
_queryResultBuffer.get(), queryHeapIndex * sizeof(UINT64));
|
||||
// commandList->EndQuery(_queryHeap.get(), D3D12_QUERY_TYPE_TIMESTAMP, queryHeapIndex + 1);
|
||||
// commandList->ResolveQueryData(_queryHeap.get(), D3D12_QUERY_TYPE_TIMESTAMP, queryHeapIndex, 2,
|
||||
// _queryResultBuffer.get(), queryHeapIndex * sizeof(UINT64));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
namespace Magpie {
|
||||
|
||||
class ComputeContext;
|
||||
|
||||
class EffectsDrawer {
|
||||
public:
|
||||
EffectsDrawer() noexcept = default;
|
||||
|
|
@ -11,13 +13,14 @@ public:
|
|||
EffectsDrawer(EffectsDrawer&&) = delete;
|
||||
|
||||
bool Initialize(
|
||||
GraphicsContext& graphicsContext,
|
||||
D3D12Context& d3d12Context,
|
||||
const ColorInfo& colorInfo,
|
||||
Size inputSize,
|
||||
Size rendererSize
|
||||
) noexcept;
|
||||
|
||||
HRESULT Draw(
|
||||
ComputeContext& computeContext,
|
||||
uint32_t frameIndex,
|
||||
ID3D12Resource* inputResource,
|
||||
ID3D12Resource* outputResource,
|
||||
|
|
@ -34,7 +37,7 @@ public:
|
|||
void OnColorInfoChanged(const ColorInfo& colorInfo) noexcept;
|
||||
|
||||
private:
|
||||
GraphicsContext* _graphicsContext = nullptr;
|
||||
D3D12Context* _d3d12Context = nullptr;
|
||||
|
||||
Size _inputSize{};
|
||||
Size _outputSize{};
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ FrameProducer::~FrameProducer() noexcept {
|
|||
|
||||
#ifdef _DEBUG
|
||||
if (_inputSrvBaseOffset != std::numeric_limits<uint32_t>::max()) {
|
||||
auto& descriptorHeap = _graphicsContext.GetDescriptorHeap();
|
||||
auto& descriptorHeap = _d3d12Context.GetDescriptorHeap();
|
||||
uint32_t maxInFlightFrameCount = ScalingWindow::Get().Options().maxProducerInFlightFrames;
|
||||
descriptorHeap.Free(_inputSrvBaseOffset, 3 * maxInFlightFrameCount + 2);
|
||||
}
|
||||
|
|
@ -40,7 +40,7 @@ FrameProducer::~FrameProducer() noexcept {
|
|||
}
|
||||
|
||||
void FrameProducer::InitializeAsync(
|
||||
const GraphicsContext& graphicsContext,
|
||||
const D3D12Context& d3d12Context,
|
||||
const ColorInfo& colorInfo,
|
||||
HMONITOR hMonSrc,
|
||||
const RECT& srcRect,
|
||||
|
|
@ -48,7 +48,7 @@ void FrameProducer::InitializeAsync(
|
|||
Size& outputSize,
|
||||
SimpleTask<bool>& task
|
||||
) noexcept {
|
||||
_graphicsContext.CopyDevice(graphicsContext);
|
||||
_d3d12Context.CopyDevice(d3d12Context);
|
||||
|
||||
_producerThread = std::thread(
|
||||
&FrameProducer::_ProducerThreadProc,
|
||||
|
|
@ -111,8 +111,8 @@ void FrameProducer::OnResizedAsync(
|
|||
return;
|
||||
}
|
||||
|
||||
hr = _graphicsContext.WaitForGpu();
|
||||
if (!_CheckResult(hr, "GraphicsContext::WaitForGpu 失败")) {
|
||||
hr = _d3d12Context.WaitForGpu();
|
||||
if (!_CheckResult(hr, "D3D12Context::WaitForGpu 失败")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -132,8 +132,8 @@ void FrameProducer::OnResizedAsync(
|
|||
}
|
||||
|
||||
// 等待渲染完成
|
||||
hr = _graphicsContext.WaitForGpu();
|
||||
if (!_CheckResult(hr, "GraphicsContext::WaitForGpu 失败")) {
|
||||
hr = _d3d12Context.WaitForGpu();
|
||||
if (!_CheckResult(hr, "D3D12Context::WaitForGpu 失败")) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
|
@ -157,8 +157,8 @@ void FrameProducer::OnColorInfoChangedAsync(
|
|||
|
||||
_isScRGB = colorInfo.kind != winrt::AdvancedColorKind::StandardDynamicRange;
|
||||
|
||||
hr = _graphicsContext.WaitForGpu();
|
||||
if (!_CheckResult(hr, "GraphicsContext::WaitForGpu 失败")) {
|
||||
hr = _d3d12Context.WaitForGpu();
|
||||
if (!_CheckResult(hr, "D3D12Context::WaitForGpu 失败")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -198,8 +198,8 @@ void FrameProducer::OnColorInfoChangedAsync(
|
|||
}
|
||||
|
||||
// 等待渲染完成
|
||||
hr = _graphicsContext.WaitForGpu();
|
||||
if (!_CheckResult(hr, "GraphicsContext::WaitForGpu 失败")) {
|
||||
hr = _d3d12Context.WaitForGpu();
|
||||
if (!_CheckResult(hr, "D3D12Context::WaitForGpu 失败")) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
|
@ -291,7 +291,7 @@ void FrameProducer::_ProducerThreadProc(
|
|||
}
|
||||
}
|
||||
|
||||
_graphicsContext.WaitForGpu();
|
||||
_d3d12Context.WaitForGpu();
|
||||
// 必须在创建线程释放
|
||||
_frameSource.reset();
|
||||
|
||||
|
|
@ -344,20 +344,22 @@ bool FrameProducer::_Initialize(
|
|||
|
||||
const ScalingOptions& options = ScalingWindow::Get().Options();
|
||||
const uint32_t maxInFlightFrameCount = options.maxProducerInFlightFrames;
|
||||
if (!_graphicsContext.InitializeAfterCopyDevice(
|
||||
if (!_d3d12Context.InitializeAfterCopyDevice(
|
||||
maxInFlightFrameCount,
|
||||
D3D12_COMMAND_QUEUE_PRIORITY_NORMAL,
|
||||
D3D12_COMMAND_LIST_TYPE_COMPUTE,
|
||||
true
|
||||
)) {
|
||||
Logger::Get().Error("初始化 GraphicsContext 失败");
|
||||
Logger::Get().Error("初始化 D3D12Context 失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
_computeContext.Initialize(_d3d12Context);
|
||||
|
||||
_isScRGB = colorInfo.kind != winrt::AdvancedColorKind::StandardDynamicRange;
|
||||
|
||||
_frameSource = std::make_unique<GraphicsCaptureFrameSource>();
|
||||
if (!_frameSource->Initialize(_graphicsContext, srcRect, hMonSrc, colorInfo)) {
|
||||
if (!_frameSource->Initialize(_d3d12Context, srcRect, hMonSrc, colorInfo)) {
|
||||
Logger::Get().Error("初始化 GraphicsCaptureFrameSource 失败");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -368,21 +370,21 @@ bool FrameProducer::_Initialize(
|
|||
uint32_t(srcRect.bottom - srcRect.top)
|
||||
};
|
||||
|
||||
if (!_effectsDrawer.Initialize(_graphicsContext, colorInfo, inputSize, rendererSize)) {
|
||||
if (!_effectsDrawer.Initialize(_d3d12Context, colorInfo, inputSize, rendererSize)) {
|
||||
Logger::Get().Error("EffectsDrawer::Initialize 失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
outputSize = _effectsDrawer.GetOutputSize();
|
||||
|
||||
if (!_frameRingBuffer.Initialize(_graphicsContext, outputSize, colorInfo)) {
|
||||
if (!_frameRingBuffer.Initialize(_d3d12Context, outputSize, colorInfo)) {
|
||||
Logger::Get().Error("初始化 FrameRingBuffer 失败");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto& descriptorHeap = _graphicsContext.GetDescriptorHeap();
|
||||
auto& descriptorHeap = _d3d12Context.GetDescriptorHeap();
|
||||
|
||||
// maxInFlightFrameCount + (maxInFlightFrameCount + 1) + (maxInFlightFrameCount + 1)
|
||||
HRESULT hr = descriptorHeap.Alloc(maxInFlightFrameCount * 3 + 2, _inputSrvBaseOffset);
|
||||
|
|
@ -418,8 +420,8 @@ bool FrameProducer::_Initialize(
|
|||
|
||||
void FrameProducer::_CreateInputDescriptors() noexcept {
|
||||
uint32_t bufferCount = ScalingWindow::Get().Options().maxProducerInFlightFrames;
|
||||
ID3D12Device5* device = _graphicsContext.GetDevice();
|
||||
auto& descriptorHeap = _graphicsContext.GetDescriptorHeap();
|
||||
ID3D12Device5* device = _d3d12Context.GetDevice();
|
||||
auto& descriptorHeap = _d3d12Context.GetDescriptorHeap();
|
||||
uint32_t descriptorSize = descriptorHeap.GetDescriptorSize();
|
||||
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE descriptorCpuHandle(descriptorHeap.GetCpuHandle(_inputSrvBaseOffset));
|
||||
|
|
@ -435,8 +437,8 @@ void FrameProducer::_CreateInputDescriptors() noexcept {
|
|||
|
||||
void FrameProducer::_CreateOutputDescriptors() noexcept {
|
||||
uint32_t bufferCount = ScalingWindow::Get().Options().maxProducerInFlightFrames + 1;
|
||||
ID3D12Device5* device = _graphicsContext.GetDevice();
|
||||
auto& descriptorHeap = _graphicsContext.GetDescriptorHeap();
|
||||
ID3D12Device5* device = _d3d12Context.GetDevice();
|
||||
auto& descriptorHeap = _d3d12Context.GetDescriptorHeap();
|
||||
uint32_t descriptorSize = descriptorHeap.GetDescriptorSize();
|
||||
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE uavCpuHandle(descriptorHeap.GetCpuHandle(_outputUavBaseOffset));
|
||||
|
|
@ -460,13 +462,13 @@ HRESULT FrameProducer::_Render() noexcept {
|
|||
_stepTimer.PrepareForRender();
|
||||
|
||||
uint32_t frameIndex;
|
||||
HRESULT hr = _graphicsContext.BeginFrame(frameIndex, nullptr);
|
||||
HRESULT hr = _d3d12Context.BeginFrame(frameIndex, nullptr);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("GraphicsContext::BeginFrame 失败", hr);
|
||||
Logger::Get().ComError("D3D12Context::BeginFrame 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
ID3D12CommandQueue* commandQueue = _graphicsContext.GetCommandQueue();
|
||||
ID3D12CommandQueue* commandQueue = _d3d12Context.GetCommandQueue();
|
||||
|
||||
uint32_t frameRingBufferIdx;
|
||||
hr = _frameRingBuffer.ProducerBeginFrame(commandQueue, frameRingBufferIdx);
|
||||
|
|
@ -482,28 +484,21 @@ HRESULT FrameProducer::_Render() noexcept {
|
|||
return hr;
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList* commandList = _graphicsContext.GetCommandList();
|
||||
_computeContext.SetDescriptorHeap(_d3d12Context.GetDescriptorHeap().GetHeap());
|
||||
|
||||
{
|
||||
ID3D12DescriptorHeap* heap = _graphicsContext.GetDescriptorHeap().GetHeap();
|
||||
commandList->SetDescriptorHeaps(1, &heap);
|
||||
}
|
||||
|
||||
// 输出和输出纹理都处于 COMMON 状态,使用结束后也应处于此状态
|
||||
// 输出和输出纹理都处于 COMMON 状态,使用结束后也应处于此状态。inputResource
|
||||
// 依赖隐式状态转换。
|
||||
ID3D12Resource* inputResource = _frameSource->GetOutput(frameSourceOutputIdx);
|
||||
ID3D12Resource* outputResource = _frameRingBuffer.GetBuffer(frameRingBufferIdx);
|
||||
|
||||
{
|
||||
D3D12_RESOURCE_BARRIER barriers[] = {
|
||||
CD3DX12_RESOURCE_BARRIER::Transition(
|
||||
inputResource, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, 0),
|
||||
CD3DX12_RESOURCE_BARRIER::Transition(
|
||||
outputResource, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, 0)
|
||||
};
|
||||
commandList->ResourceBarrier((UINT)std::size(barriers), barriers);
|
||||
}
|
||||
_computeContext.InsertTransitionBarrier(
|
||||
outputResource,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS
|
||||
);
|
||||
|
||||
hr = _effectsDrawer.Draw(
|
||||
_computeContext,
|
||||
frameIndex,
|
||||
inputResource,
|
||||
outputResource,
|
||||
|
|
@ -515,23 +510,13 @@ HRESULT FrameProducer::_Render() noexcept {
|
|||
return hr;
|
||||
}
|
||||
|
||||
{
|
||||
D3D12_RESOURCE_BARRIER barriers[] = {
|
||||
CD3DX12_RESOURCE_BARRIER::Transition(
|
||||
inputResource, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COMMON, 0),
|
||||
CD3DX12_RESOURCE_BARRIER::Transition(
|
||||
outputResource, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COMMON, 0)
|
||||
};
|
||||
commandList->ResourceBarrier((UINT)std::size(barriers), barriers);
|
||||
}
|
||||
_computeContext.InsertTransitionBarrier(
|
||||
outputResource,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
|
||||
D3D12_RESOURCE_STATE_COMMON
|
||||
);
|
||||
|
||||
hr = commandList->Close();
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("ID3D12GraphicsCommandList::Close 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
commandQueue->ExecuteCommandLists(1, CommandListCast(&commandList));
|
||||
_computeContext.Execute(commandQueue);
|
||||
|
||||
hr = _frameRingBuffer.ProducerEndFrame(commandQueue);
|
||||
if (FAILED(hr)) {
|
||||
|
|
@ -539,9 +524,9 @@ HRESULT FrameProducer::_Render() noexcept {
|
|||
return hr;
|
||||
}
|
||||
|
||||
hr = _graphicsContext.EndFrame();
|
||||
hr = _d3d12Context.EndFrame();
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("GraphicsContext::EndFrame 失败", hr);
|
||||
Logger::Get().ComError("D3D12Context::EndFrame 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include "GraphicsContext.h"
|
||||
#include "CommandContext.h"
|
||||
#include "D3D12Context.h"
|
||||
#include "EffectsDrawer.h"
|
||||
#include "FrameRingBuffer.h"
|
||||
#include "StepTimer.h"
|
||||
|
|
@ -18,7 +19,7 @@ public:
|
|||
~FrameProducer() noexcept;
|
||||
|
||||
void InitializeAsync(
|
||||
const GraphicsContext& graphicsContext,
|
||||
const D3D12Context& d3d12Context,
|
||||
const ColorInfo& colorInfo,
|
||||
HMONITOR hMonSrc,
|
||||
const RECT& srcRect,
|
||||
|
|
@ -84,7 +85,8 @@ private:
|
|||
|
||||
std::thread _monitorThread;
|
||||
|
||||
GraphicsContext _graphicsContext;
|
||||
D3D12Context _d3d12Context;
|
||||
ComputeContext _computeContext;
|
||||
FrameRingBuffer _frameRingBuffer;
|
||||
StepTimer _stepTimer;
|
||||
std::unique_ptr<GraphicsCaptureFrameSource> _frameSource;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include "pch.h"
|
||||
#include "FrameRingBuffer.h"
|
||||
#include "GraphicsContext.h"
|
||||
#include "D3D12Context.h"
|
||||
#include "Logger.h"
|
||||
#include "ScalingWindow.h"
|
||||
#include "DebugInfo.h"
|
||||
|
|
@ -9,11 +9,11 @@
|
|||
namespace Magpie {
|
||||
|
||||
bool FrameRingBuffer::Initialize(
|
||||
GraphicsContext& graphicsContext,
|
||||
D3D12Context& d3d12Context,
|
||||
Size size,
|
||||
const ColorInfo& colorInfo
|
||||
) noexcept {
|
||||
_graphicsContext = &graphicsContext;
|
||||
_d3d12Context = &d3d12Context;
|
||||
_size = size;
|
||||
_isScRGB = colorInfo.kind != winrt::AdvancedColorKind::StandardDynamicRange;
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ bool FrameRingBuffer::Initialize(
|
|||
// 消费者应落后于生产者
|
||||
_curConsumerIdx = slotCount - 1;
|
||||
|
||||
ID3D12Device5* device = graphicsContext.GetDevice();
|
||||
ID3D12Device5* device = d3d12Context.GetDevice();
|
||||
|
||||
HRESULT hr = device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&_consumerFence));
|
||||
if (FAILED(hr)) {
|
||||
|
|
@ -236,7 +236,7 @@ HRESULT FrameRingBuffer::OnColorInfoChanged(const ColorInfo& colorInfo) noexcept
|
|||
}
|
||||
|
||||
HRESULT FrameRingBuffer::_CreateBuffers() noexcept {
|
||||
ID3D12Device5* device = _graphicsContext->GetDevice();
|
||||
ID3D12Device5* device = _d3d12Context->GetDevice();
|
||||
|
||||
CD3DX12_HEAP_PROPERTIES heapProps(D3D12_HEAP_TYPE_DEFAULT);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
namespace Magpie {
|
||||
|
||||
class GraphicsContext;
|
||||
class D3D12Context;
|
||||
|
||||
class FrameRingBuffer {
|
||||
public:
|
||||
|
|
@ -12,7 +12,7 @@ public:
|
|||
FrameRingBuffer(FrameRingBuffer&&) = delete;
|
||||
|
||||
bool Initialize(
|
||||
GraphicsContext& graphicsContext,
|
||||
D3D12Context& d3d12Context,
|
||||
Size size,
|
||||
const ColorInfo& colorInfo
|
||||
) noexcept;
|
||||
|
|
@ -50,7 +50,7 @@ private:
|
|||
HRESULT _CreateBuffers() noexcept;
|
||||
|
||||
// 只在生产者线程访问
|
||||
GraphicsContext* _graphicsContext = nullptr;
|
||||
D3D12Context* _d3d12Context = nullptr;
|
||||
|
||||
wil::srwlock _lock;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
#include "DirectXHelper.h"
|
||||
#include "DirtyRectsOptimizer.h"
|
||||
#include "DuplicateFrameChecker.h"
|
||||
#include "GraphicsContext.h"
|
||||
#include "D3D12Context.h"
|
||||
#include "Logger.h"
|
||||
#include "ScalingWindow.h"
|
||||
#include "Win32Helper.h"
|
||||
|
|
@ -142,14 +142,14 @@ static uint32_t CalcCaptureFrameCount() noexcept {
|
|||
}
|
||||
|
||||
bool GraphicsCaptureFrameSource::Initialize(
|
||||
GraphicsContext& graphicsContext,
|
||||
D3D12Context& d3d12Context,
|
||||
const RECT& srcRect,
|
||||
HMONITOR hMonSrc,
|
||||
const ColorInfo& colorInfo
|
||||
) noexcept {
|
||||
assert(hMonSrc);
|
||||
|
||||
_graphicsContext = &graphicsContext;
|
||||
_d3d12Context = &d3d12Context;
|
||||
_isScRGB = colorInfo.kind != winrt::AdvancedColorKind::StandardDynamicRange;
|
||||
|
||||
if (!winrt::GraphicsCaptureSession::IsSupported()) {
|
||||
|
|
@ -200,7 +200,7 @@ bool GraphicsCaptureFrameSource::Initialize(
|
|||
|
||||
_producerThreadId.store(GetCurrentThreadId(), std::memory_order_relaxed);
|
||||
|
||||
ID3D12Device5* device = graphicsContext.GetDevice();
|
||||
ID3D12Device5* device = d3d12Context.GetDevice();
|
||||
|
||||
{
|
||||
D3D12_COMMAND_QUEUE_DESC queueDesc = { .Type = D3D12_COMMAND_LIST_TYPE_COPY };
|
||||
|
|
@ -313,7 +313,7 @@ HRESULT GraphicsCaptureFrameSource::CheckForNewFrame(bool& isNewFrameAvailable)
|
|||
}
|
||||
}
|
||||
|
||||
ID3D12Device5* dfDevice = _bridgeDevice ? _bridgeDevice.get() : _graphicsContext->GetDevice();
|
||||
ID3D12Device5* dfDevice = _bridgeDevice ? _bridgeDevice.get() : _d3d12Context->GetDevice();
|
||||
|
||||
winrt::com_ptr<ID3D11Texture2D> d3d11Texture;
|
||||
{
|
||||
|
|
@ -609,9 +609,9 @@ HRESULT GraphicsCaptureFrameSource::Update(uint32_t& outputIdx) noexcept {
|
|||
_copyCommandQueue->ExecuteCommandLists(1, &t);
|
||||
}
|
||||
|
||||
hr = _graphicsContext->WaitForCommandQueue(_copyCommandQueue.get());
|
||||
hr = _d3d12Context->WaitForCommandQueue(_copyCommandQueue.get());
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("GraphicsContext::WaitForCommandQueue 失败", hr);
|
||||
Logger::Get().ComError("D3D12Context::WaitForCommandQueue 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
|
@ -649,9 +649,9 @@ HRESULT GraphicsCaptureFrameSource::OnCursorVisibilityChanged(bool isVisible, bo
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT hr = _graphicsContext->WaitForGpu();
|
||||
HRESULT hr = _d3d12Context->WaitForGpu();
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("GraphicsContext::WaitForGpu 失败", hr);
|
||||
Logger::Get().ComError("D3D12Context::WaitForGpu 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
|
@ -674,12 +674,12 @@ HRESULT GraphicsCaptureFrameSource::OnCursorVisibilityChanged(bool isVisible, bo
|
|||
bool GraphicsCaptureFrameSource::_CreateCaptureDevice(HMONITOR hMonSrc) noexcept {
|
||||
// 查找源窗口所在屏幕连接的适配器
|
||||
winrt::com_ptr<IDXGIAdapter1> srcMonAdapter =
|
||||
FindAdapterOfMonitor(_graphicsContext->GetDXGIFactoryForEnumingAdapters(), hMonSrc);
|
||||
FindAdapterOfMonitor(_d3d12Context->GetDXGIFactoryForEnumingAdapters(), hMonSrc);
|
||||
if (srcMonAdapter) {
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
HRESULT hr = srcMonAdapter->GetDesc(&desc);
|
||||
if (SUCCEEDED(hr)) {
|
||||
if (desc.AdapterLuid != _graphicsContext->GetDevice()->GetAdapterLuid()) {
|
||||
if (desc.AdapterLuid != _d3d12Context->GetDevice()->GetAdapterLuid()) {
|
||||
// 跨适配器捕获
|
||||
if (!_CreateBridgeDeviceResources(srcMonAdapter.get())) {
|
||||
// 失败则使用渲染设备捕获,交给 WGC 中转
|
||||
|
|
@ -714,7 +714,7 @@ bool GraphicsCaptureFrameSource::_CreateCaptureDevice(HMONITOR hMonSrc) noexcept
|
|||
winrt::com_ptr<ID3D11DeviceContext> d3dDC;
|
||||
D3D_FEATURE_LEVEL featureLevel;
|
||||
HRESULT hr = D3D11CreateDevice(
|
||||
srcMonAdapter ? srcMonAdapter.get() : _graphicsContext->GetDXGIAdapter(),
|
||||
srcMonAdapter ? srcMonAdapter.get() : _d3d12Context->GetDXGIAdapter(),
|
||||
D3D_DRIVER_TYPE_UNKNOWN,
|
||||
nullptr,
|
||||
createDeviceFlags,
|
||||
|
|
@ -817,7 +817,7 @@ bool GraphicsCaptureFrameSource::_CreateBridgeDeviceResources(IDXGIAdapter1* dxg
|
|||
}
|
||||
}
|
||||
|
||||
ID3D12Device5* device = _graphicsContext->GetDevice();
|
||||
ID3D12Device5* device = _d3d12Context->GetDevice();
|
||||
const uint32_t frameCount = ScalingWindow::Get().Options().maxProducerInFlightFrames;
|
||||
|
||||
_crossAdapterSlots.resize(frameCount);
|
||||
|
|
@ -876,7 +876,7 @@ bool GraphicsCaptureFrameSource::_CreateBridgeDeviceResources(IDXGIAdapter1* dxg
|
|||
}
|
||||
|
||||
HRESULT GraphicsCaptureFrameSource::_CreateDisplayDependentResources() noexcept {
|
||||
ID3D12Device5* device = _graphicsContext->GetDevice();
|
||||
ID3D12Device5* device = _d3d12Context->GetDevice();
|
||||
|
||||
// 创建每帧输出纹理
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
namespace Magpie {
|
||||
|
||||
class GraphicsContext;
|
||||
class D3D12Context;
|
||||
class DuplicateFrameChecker;
|
||||
|
||||
enum class FrameSourceState {
|
||||
|
|
@ -25,7 +25,7 @@ public:
|
|||
~GraphicsCaptureFrameSource() noexcept;
|
||||
|
||||
bool Initialize(
|
||||
GraphicsContext& graphicsContext,
|
||||
D3D12Context& d3d12Context,
|
||||
const RECT& srcRect,
|
||||
HMONITOR hMonSrc,
|
||||
const ColorInfo& colorInfo
|
||||
|
|
@ -69,7 +69,7 @@ private:
|
|||
|
||||
void _StopCapture() noexcept;
|
||||
|
||||
GraphicsContext* _graphicsContext = nullptr;
|
||||
D3D12Context* _d3d12Context = nullptr;
|
||||
|
||||
std::atomic<DWORD> _producerThreadId;
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
<ClInclude Include="BackendDescriptorStore.h" />
|
||||
<ClInclude Include="CatmullRomDrawer.h" />
|
||||
<ClInclude Include="ColorHelper.h" />
|
||||
<ClInclude Include="CommandContext.h" />
|
||||
<ClInclude Include="CompSwapchainPresenter.h" />
|
||||
<ClInclude Include="CursorDrawer.h" />
|
||||
<ClInclude Include="CursorManager.h" />
|
||||
|
|
@ -77,7 +78,7 @@
|
|||
<ClInclude Include="ShaderEffectDrawer.h" />
|
||||
<ClInclude Include="GDIFrameSource.h" />
|
||||
<ClInclude Include="GraphicsCaptureFrameSource.h" />
|
||||
<ClInclude Include="GraphicsContext.h" />
|
||||
<ClInclude Include="D3D12Context.h" />
|
||||
<ClInclude Include="ImGuiBackend.h" />
|
||||
<ClInclude Include="ImGuiFontsCacheManager.h" />
|
||||
<ClInclude Include="OverlayHelper.h" />
|
||||
|
|
@ -110,6 +111,7 @@
|
|||
<ItemGroup>
|
||||
<ClCompile Include="BackendDescriptorStore.cpp" />
|
||||
<ClCompile Include="CatmullRomDrawer.cpp" />
|
||||
<ClCompile Include="CommandContext.cpp" />
|
||||
<ClCompile Include="CompSwapchainPresenter.cpp" />
|
||||
<ClCompile Include="CursorDrawer.cpp" />
|
||||
<ClCompile Include="CursorManager.cpp" />
|
||||
|
|
@ -134,7 +136,7 @@
|
|||
<ClCompile Include="ShaderEffectDrawer.cpp" />
|
||||
<ClCompile Include="GDIFrameSource.cpp" />
|
||||
<ClCompile Include="GraphicsCaptureFrameSource.cpp" />
|
||||
<ClCompile Include="GraphicsContext.cpp" />
|
||||
<ClCompile Include="D3D12Context.cpp" />
|
||||
<ClCompile Include="ImGuiBackend.cpp" />
|
||||
<ClCompile Include="ImGuiFontsCacheManager.cpp" />
|
||||
<ClCompile Include="OverlayHelper.cpp" />
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@
|
|||
<ClInclude Include="GraphicsCaptureFrameSource.h">
|
||||
<Filter>Capture</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GraphicsContext.h">
|
||||
<ClInclude Include="D3D12Context.h">
|
||||
<Filter>Render</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FrameProducer.h">
|
||||
|
|
@ -195,6 +195,9 @@
|
|||
<ClInclude Include="ColorHelper.h">
|
||||
<Filter>Helpers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CommandContext.h">
|
||||
<Filter>Render</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ScalingRuntime.cpp" />
|
||||
|
|
@ -292,7 +295,7 @@
|
|||
<ClCompile Include="GraphicsCaptureFrameSource.cpp">
|
||||
<Filter>Capture</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GraphicsContext.cpp">
|
||||
<ClCompile Include="D3D12Context.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FrameProducer.cpp">
|
||||
|
|
@ -326,6 +329,9 @@
|
|||
<ClCompile Include="DescriptorHeap.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CommandContext.cpp">
|
||||
<Filter>Render</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<FxCompile Include="shaders\MaskedCursorPS.hlsl">
|
||||
|
|
|
|||
|
|
@ -13,10 +13,15 @@
|
|||
|
||||
namespace Magpie {
|
||||
|
||||
// 如果描述符大小为 32 字节,描述符堆消耗 2MiB 显存
|
||||
static uint32_t CSU_HEAP_CAPACITY = 65536;
|
||||
// 目前只有渲染到后缓冲和缩放光标时需要 RTV
|
||||
static uint32_t RTV_HEAP_CAPACITY = 1024;
|
||||
|
||||
Renderer2::Renderer2() noexcept {}
|
||||
|
||||
Renderer2::~Renderer2() noexcept {
|
||||
_graphicsContext.WaitForGpu();
|
||||
_d3d12Context.WaitForGpu();
|
||||
}
|
||||
|
||||
static void SetGpuPriority() noexcept {
|
||||
|
|
@ -42,7 +47,7 @@ ScalingError Renderer2::Initialize(
|
|||
SetGpuPriority();
|
||||
|
||||
const ScalingOptions& options = ScalingWindow::Get().Options();
|
||||
if (!_graphicsContext.Initialize(
|
||||
if (!_d3d12Context.Initialize(
|
||||
options.graphicsCardId,
|
||||
options.Is3DGameMode() ? 2 : 6,
|
||||
D3D12_COMMAND_QUEUE_PRIORITY_HIGH,
|
||||
|
|
@ -50,11 +55,11 @@ ScalingError Renderer2::Initialize(
|
|||
_csuDescriptorHeap,
|
||||
_rtvDescriptorHeap
|
||||
)) {
|
||||
Logger::Get().Error("初始化 GraphicsContext 失败");
|
||||
Logger::Get().Error("初始化 D3D12Context 失败");
|
||||
return ScalingError::ScalingFailedGeneral;
|
||||
}
|
||||
|
||||
ID3D12Device5* device = _graphicsContext.GetDevice();
|
||||
ID3D12Device5* device = _d3d12Context.GetDevice();
|
||||
|
||||
#ifdef MP_DEBUG_INFO
|
||||
{
|
||||
|
|
@ -86,6 +91,22 @@ ScalingError Renderer2::Initialize(
|
|||
}
|
||||
#endif
|
||||
|
||||
if (!_csuDescriptorHeap.Initialize(
|
||||
device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, CSU_HEAP_CAPACITY)
|
||||
) {
|
||||
Logger::Get().Error("DescriptorHeap::Initialize 失败");
|
||||
return ScalingError::ScalingFailedGeneral;
|
||||
}
|
||||
|
||||
if (!_rtvDescriptorHeap.Initialize(
|
||||
device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, RTV_HEAP_CAPACITY)
|
||||
) {
|
||||
Logger::Get().Error("DescriptorHeap::Initialize 失败");
|
||||
return ScalingError::ScalingFailedGeneral;
|
||||
}
|
||||
|
||||
_graphicsContext.Initialize(_d3d12Context);
|
||||
|
||||
// 失败则回落到使用传统方法获取颜色显示能力
|
||||
_TryInitDisplayInfo();
|
||||
|
||||
|
|
@ -102,10 +123,10 @@ ScalingError Renderer2::Initialize(
|
|||
Size outputSize;
|
||||
SimpleTask<bool> task;
|
||||
_frameProducer.InitializeAsync(
|
||||
_graphicsContext, _colorInfo, hMonitor, srcRect, rendererSize, outputSize, task);
|
||||
_d3d12Context, _colorInfo, hMonitor, srcRect, rendererSize, outputSize, task);
|
||||
|
||||
_presenter = std::make_unique<SwapChainPresenter>();
|
||||
if (!_presenter->Initialize(_graphicsContext, hwndAttach, rendererSize, _colorInfo)) {
|
||||
if (!_presenter->Initialize(_d3d12Context, hwndAttach, rendererSize, _colorInfo)) {
|
||||
Logger::Get().Error("SwapChainPresenter::Initialize 失败");
|
||||
return ScalingError::ScalingFailedGeneral;
|
||||
}
|
||||
|
|
@ -145,7 +166,7 @@ ScalingError Renderer2::Initialize(
|
|||
|
||||
winrt::com_ptr<ID3DBlob> signature;
|
||||
HRESULT hr = D3DX12SerializeVersionedRootSignature(
|
||||
&rootSignatureDesc, _graphicsContext.GetRootSignatureVersion(), signature.put(), nullptr);
|
||||
&rootSignatureDesc, _d3d12Context.GetRootSignatureVersion(), signature.put(), nullptr);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("D3DX12SerializeVersionedRootSignature 失败", hr);
|
||||
return ScalingError::ScalingFailedGeneral;
|
||||
|
|
@ -196,7 +217,7 @@ ScalingError Renderer2::Initialize(
|
|||
destRect.right = rendererRect.left + (LONG)_outputRect.right;
|
||||
destRect.bottom = rendererRect.top + (LONG)_outputRect.bottom;
|
||||
|
||||
if (!_cursorDrawer.Initialize(_graphicsContext, srcRect, rendererRect, destRect, _colorInfo)) {
|
||||
if (!_cursorDrawer.Initialize(_d3d12Context, srcRect, rendererRect, destRect, _colorInfo)) {
|
||||
Logger::Get().Error("CursorDrawer::Initialize 失败");
|
||||
return ScalingError::ScalingFailedGeneral;
|
||||
}
|
||||
|
|
@ -273,7 +294,7 @@ void Renderer2::OnResized(const RECT& rendererRect, RECT& destRect) noexcept {
|
|||
}
|
||||
|
||||
// 确保消费者不再使用环形缓冲区
|
||||
if (!_CheckResult(_graphicsContext.WaitForGpu(), "GraphicsContext::WaitForGpu 失败")) {
|
||||
if (!_CheckResult(_d3d12Context.WaitForGpu(), "D3D12Context::WaitForGpu 失败")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -435,7 +456,7 @@ bool Renderer2::_UpdateColorInfo() noexcept {
|
|||
return true;
|
||||
}
|
||||
|
||||
IDXGIFactory7* dxgiFactory = _graphicsContext.GetDXGIFactoryForEnumingAdapters();
|
||||
IDXGIFactory7* dxgiFactory = _d3d12Context.GetDXGIFactoryForEnumingAdapters();
|
||||
if (!dxgiFactory) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -488,9 +509,9 @@ HRESULT Renderer2::_UpdateColorSpace() noexcept {
|
|||
}
|
||||
|
||||
// 确保消费者不再使用环形缓冲区
|
||||
HRESULT hr = _graphicsContext.WaitForGpu();
|
||||
HRESULT hr = _d3d12Context.WaitForGpu();
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("GraphicsContext::WaitForGpu 失败", hr);
|
||||
Logger::Get().ComError("D3D12Context::WaitForGpu 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
|
@ -528,35 +549,27 @@ HRESULT Renderer2::_RenderImpl(bool waitForGpu) noexcept {
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
// SwapChain::BeginFrame 和 GraphicsContext::BeginFrame 无顺序要求,不过
|
||||
// SwapChain::BeginFrame 和 D3D12Context::BeginFrame 无顺序要求,不过
|
||||
// 前者通常等待时间更久,将它放在前面可以减少等待次数。
|
||||
ID3D12Resource* backBuffer;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle, rawRtvHandle;
|
||||
_presenter->BeginFrame(&backBuffer, rtvHandle, rawRtvHandle);
|
||||
uint32_t rtvOffset, rawRtvOffset;
|
||||
_presenter->BeginFrame(&backBuffer, rtvOffset, rawRtvOffset);
|
||||
|
||||
uint32_t frameIndex;
|
||||
HRESULT hr = _graphicsContext.BeginFrame(frameIndex, _pipelineState.get());
|
||||
HRESULT hr = _d3d12Context.BeginFrame(frameIndex, _pipelineState.get());
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("GraphicsContext::BeginFrame 失败", hr);
|
||||
Logger::Get().ComError("D3D12Context::BeginFrame 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
ID3D12GraphicsCommandList* commandList = _graphicsContext.GetCommandList();
|
||||
_graphicsContext.SetDescriptorHeap(_csuDescriptorHeap.GetHeap());
|
||||
|
||||
{
|
||||
ID3D12DescriptorHeap* heap = _csuDescriptorHeap.GetHeap();
|
||||
commandList->SetDescriptorHeaps(1, &heap);
|
||||
}
|
||||
|
||||
commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
_graphicsContext.IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
|
||||
{
|
||||
CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(
|
||||
backBuffer, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET, 0);
|
||||
commandList->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
_graphicsContext.InsertTransitionBarrier(
|
||||
backBuffer, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
|
||||
commandList->SetGraphicsRootSignature(_rootSignature.get());
|
||||
_graphicsContext.SetRootSignature(_rootSignature.get());
|
||||
|
||||
const Size rendererSize = _presenter->GetSize();
|
||||
|
||||
|
|
@ -570,56 +583,41 @@ HRESULT Renderer2::_RenderImpl(bool waitForGpu) noexcept {
|
|||
_outputRect.left / -outputWidth,
|
||||
_outputRect.top / -outputHeight
|
||||
};
|
||||
commandList->SetGraphicsRoot32BitConstants(0, (UINT)std::size(constants), constants, 0);
|
||||
_graphicsContext.SetRoot32BitConstants(0, (uint32_t)std::size(constants), constants);
|
||||
}
|
||||
|
||||
commandList->SetGraphicsRootDescriptorTable(
|
||||
1, _csuDescriptorHeap.GetGpuHandle(curFrameSrvOffset));
|
||||
_graphicsContext.SetRootDescriptorTable(1, curFrameSrvOffset);
|
||||
|
||||
{
|
||||
CD3DX12_VIEWPORT viewport(0.0f, 0.0f, (float)rendererSize.width, (float)rendererSize.height);
|
||||
commandList->RSSetViewports(1, &viewport);
|
||||
}
|
||||
{
|
||||
CD3DX12_RECT scissorRect(0, 0, (LONG)rendererSize.width, (LONG)rendererSize.height);
|
||||
commandList->RSSetScissorRects(1, &scissorRect);
|
||||
}
|
||||
_graphicsContext.RSSetViewportAndScissorRect(CD3DX12_RECT(
|
||||
0, 0, (LONG)rendererSize.width, (LONG)rendererSize.height));
|
||||
|
||||
_graphicsContext.OMSetRenderTarget(rtvOffset);
|
||||
|
||||
commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr);
|
||||
commandList->DrawInstanced(3, 1, 0, 0);
|
||||
_graphicsContext.Draw(3);
|
||||
|
||||
// 为了和 OS 保持一致,SDR 下在 sRGB 空间中混合
|
||||
if (_colorInfo.kind == winrt::AdvancedColorKind::StandardDynamicRange) {
|
||||
commandList->OMSetRenderTargets(1, &rawRtvHandle, FALSE, nullptr);
|
||||
_graphicsContext.OMSetRenderTarget(rawRtvOffset);
|
||||
}
|
||||
|
||||
hr = _cursorDrawer.Draw(
|
||||
completedFenceValue,
|
||||
fenceValueToSignal,
|
||||
curFrameSrvOffset,
|
||||
_colorInfo.kind == winrt::AdvancedColorKind::StandardDynamicRange ? rawRtvHandle : rtvHandle,
|
||||
nullptr
|
||||
);
|
||||
hr = _cursorDrawer.Draw(_graphicsContext, completedFenceValue, fenceValueToSignal,
|
||||
curFrameSrvOffset, nullptr);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("CursorDrawer::Draw 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
{
|
||||
CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(
|
||||
backBuffer, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT, 0);
|
||||
commandList->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
_graphicsContext.InsertTransitionBarrier(
|
||||
backBuffer, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
|
||||
|
||||
hr = commandList->Close();
|
||||
ID3D12CommandQueue* commandQueue = _d3d12Context.GetCommandQueue();
|
||||
|
||||
hr = _graphicsContext.Execute(commandQueue);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("ID3D12GraphicsCommandList::Close 失败", hr);
|
||||
Logger::Get().ComError("CommandContext::Execute 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
ID3D12CommandQueue* commandQueue = _graphicsContext.GetCommandQueue();
|
||||
commandQueue->ExecuteCommandLists(1, CommandListCast(&commandList));
|
||||
|
||||
hr =_frameProducer.ConsumerEndFrame(commandQueue, fenceValueToSignal);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("FrameProducer::ConsumerEndFrame 失败", hr);
|
||||
|
|
@ -632,10 +630,10 @@ HRESULT Renderer2::_RenderImpl(bool waitForGpu) noexcept {
|
|||
return hr;
|
||||
}
|
||||
|
||||
// GraphicsContext::EndFrame 必须在 SwapChain::EndFrame 之后
|
||||
hr = _graphicsContext.EndFrame();
|
||||
// D3D12Context::EndFrame 必须在 SwapChain::EndFrame 之后
|
||||
hr = _d3d12Context.EndFrame();
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("GraphicsContext::EndFrame 失败", hr);
|
||||
Logger::Get().ComError("D3D12Context::EndFrame 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
#pragma once
|
||||
#include "CursorDrawer.h"
|
||||
#include "CommandContext.h"
|
||||
#include "FrameProducer.h"
|
||||
#include "GraphicsContext.h"
|
||||
#include "D3D12Context.h"
|
||||
#include "DescriptorHeap.h"
|
||||
#include "ScalingOptions.h"
|
||||
|
||||
|
|
@ -86,9 +87,10 @@ private:
|
|||
|
||||
Rect _outputRect{};
|
||||
|
||||
// 由多个 GraphicsContext 共享
|
||||
// 由多个 D3D12Context 共享
|
||||
DescriptorHeap _csuDescriptorHeap;
|
||||
DescriptorHeap _rtvDescriptorHeap;
|
||||
D3D12Context _d3d12Context;
|
||||
GraphicsContext _graphicsContext;
|
||||
FrameProducer _frameProducer;
|
||||
CursorDrawer _cursorDrawer;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include "SwapChainPresenter.h"
|
||||
#include "DebugInfo.h"
|
||||
#include "DescriptorHeap.h"
|
||||
#include "GraphicsContext.h"
|
||||
#include "D3D12Context.h"
|
||||
#include "Logger.h"
|
||||
#include "Win32Helper.h"
|
||||
#include <dcomp.h>
|
||||
|
|
@ -25,7 +25,7 @@ SwapChainPresenter::~SwapChainPresenter() noexcept {
|
|||
}
|
||||
|
||||
bool SwapChainPresenter::Initialize(
|
||||
GraphicsContext& graphicContext,
|
||||
D3D12Context& graphicContext,
|
||||
HWND hwndAttach,
|
||||
Size size,
|
||||
const ColorInfo& colorInfo
|
||||
|
|
@ -142,18 +142,17 @@ bool SwapChainPresenter::Initialize(
|
|||
|
||||
void SwapChainPresenter::BeginFrame(
|
||||
ID3D12Resource** backBuffer,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE& rtvHandle,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE& rawRtvHandle
|
||||
uint32_t& rtvOffset,
|
||||
uint32_t& rawRtvOffse
|
||||
) noexcept {
|
||||
_frameLatencyWaitableObject.wait(1000);
|
||||
|
||||
const uint32_t curBufferIndex = _dxgiSwapChain->GetCurrentBackBufferIndex();
|
||||
*backBuffer = _frameBuffers[curBufferIndex].get();
|
||||
|
||||
auto& rtvDescriptorHeap =_graphicContext->GetDescriptorHeap(true);
|
||||
rtvHandle = rtvDescriptorHeap.GetCpuHandle(_rtvBaseOffset + curBufferIndex);
|
||||
rtvOffset = _rtvBaseOffset + curBufferIndex;
|
||||
if (!_isScRGB) {
|
||||
rawRtvHandle = rtvDescriptorHeap.GetCpuHandle(_rawRtvBaseOffset + curBufferIndex);
|
||||
rawRtvOffse = _rawRtvBaseOffset + curBufferIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -278,7 +277,7 @@ HRESULT SwapChainPresenter::EndFrame(bool waitForGpu) noexcept {
|
|||
// 等待渲染完成
|
||||
HRESULT hr = _graphicContext->WaitForGpu();
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("GraphicsContext::WaitForGPU", hr);
|
||||
Logger::Get().ComError("D3D12Context::WaitForGPU", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
|
@ -349,7 +348,7 @@ HRESULT SwapChainPresenter::OnResizeEnded() noexcept {
|
|||
// 调用此方法前没等待 GPU
|
||||
HRESULT hr = _graphicContext->WaitForGpu();
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("GraphicsContext::WaitForGPU", hr);
|
||||
Logger::Get().ComError("D3D12Context::WaitForGPU", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Magpie {
|
||||
|
||||
class GraphicsContext;
|
||||
class D3D12Context;
|
||||
|
||||
class SwapChainPresenter {
|
||||
public:
|
||||
|
|
@ -13,17 +13,17 @@ public:
|
|||
~SwapChainPresenter() noexcept;
|
||||
|
||||
bool Initialize(
|
||||
GraphicsContext& graphicContext,
|
||||
D3D12Context& graphicContext,
|
||||
HWND hwndAttach,
|
||||
Size size,
|
||||
const ColorInfo& colorInfo
|
||||
) noexcept;
|
||||
|
||||
// SDR 下 rawRtvHandle 不做伽马校正,用于渲染光标
|
||||
// SDR 下 rawRtvOffse 不做伽马校正,用于渲染光标
|
||||
void BeginFrame(
|
||||
ID3D12Resource** backBuffer,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE& rtvHandle,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE& rawRtvHandle
|
||||
uint32_t& rtvOffset,
|
||||
uint32_t& rawRtvOffse
|
||||
) noexcept;
|
||||
|
||||
HRESULT EndFrame(bool waitForGpu = false) noexcept;
|
||||
|
|
@ -43,7 +43,7 @@ private:
|
|||
|
||||
HRESULT _CreateDisplayDependentResources() noexcept;
|
||||
|
||||
GraphicsContext* _graphicContext = nullptr;
|
||||
D3D12Context* _graphicContext = nullptr;
|
||||
|
||||
winrt::com_ptr<IDXGISwapChain4> _dxgiSwapChain;
|
||||
wil::unique_event_nothrow _frameLatencyWaitableObject;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue