refactor: 封装 command list 接口

This commit is contained in:
Xu 2026-03-12 11:10:00 +08:00
commit de3afc9876
22 changed files with 673 additions and 419 deletions

View file

@ -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(),

View file

@ -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;

View 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();
}
}

View 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();
};
}

View file

@ -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);

View file

@ -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{};

View file

@ -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;

View file

@ -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,

View file

@ -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;
}

View file

@ -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{};

View file

@ -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;
}

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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();
// 创建每帧输出纹理
{

View file

@ -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;

View file

@ -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" />

View file

@ -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">

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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;