mirror of
https://github.com/Blinue/Magpie.git
synced 2026-06-24 02:04:10 +00:00
feat: 实现动态描述符堆 (p2)
This commit is contained in:
parent
65502115e6
commit
cb2ced9b42
9 changed files with 165 additions and 219 deletions
|
|
@ -13,8 +13,7 @@ bool EffectsDrawer::Initialize(
|
|||
GraphicsContext& graphicsContext,
|
||||
const ColorInfo& colorInfo,
|
||||
Size inputSize,
|
||||
Size rendererSize,
|
||||
SmallVectorImpl<winrt::com_ptr<ID3D12Resource>>& outputResources
|
||||
Size rendererSize
|
||||
) noexcept {
|
||||
_graphicsContext = &graphicsContext;
|
||||
_isScRGB = colorInfo.kind != winrt::AdvancedColorKind::StandardDynamicRange;
|
||||
|
|
@ -51,12 +50,6 @@ bool EffectsDrawer::Initialize(
|
|||
Logger::Get().ComError("CatmullRomDrawer::Initialize 失败", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = _CreateOutputResources(outputResources);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("_CreateOutputResources 失败", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
// 每帧两个时间戳
|
||||
|
|
@ -122,16 +115,15 @@ HRESULT EffectsDrawer::Draw(
|
|||
}
|
||||
|
||||
ID3D12GraphicsCommandList* commandList = _graphicsContext->GetCommandList();
|
||||
auto& dynamicDescriptorHeap = _graphicsContext->GetDynamicDescriptorHeap();
|
||||
|
||||
{
|
||||
ID3D12DescriptorHeap* t = dynamicDescriptorHeap.GetHeap();
|
||||
ID3D12DescriptorHeap* t = _graphicsContext->GetDynamicDescriptorHeap().GetHeap();
|
||||
commandList->SetDescriptorHeaps(1, &t);
|
||||
}
|
||||
|
||||
commandList->EndQuery(_queryHeap.get(), D3D12_QUERY_TYPE_TIMESTAMP, queryHeapIndex);
|
||||
|
||||
_catmullRomDrawer->Draw(_inputSize, _outputSize, inputSrvHandle, outputUavHandle, !_isScRGB);
|
||||
_catmullRomDrawer->Draw(_inputSize, _outputSize, inputSrvHandle, outputUavHandle, false);
|
||||
|
||||
commandList->EndQuery(_queryHeap.get(), D3D12_QUERY_TYPE_TIMESTAMP, queryHeapIndex + 1);
|
||||
commandList->ResolveQueryData(_queryHeap.get(), D3D12_QUERY_TYPE_TIMESTAMP, queryHeapIndex, 2,
|
||||
|
|
@ -140,70 +132,13 @@ HRESULT EffectsDrawer::Draw(
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT EffectsDrawer::OnResized(
|
||||
Size rendererSize,
|
||||
SmallVectorImpl<winrt::com_ptr<ID3D12Resource>>& outputResources
|
||||
) noexcept {
|
||||
HRESULT EffectsDrawer::OnResized(Size rendererSize) noexcept {
|
||||
_outputSize = rendererSize;
|
||||
|
||||
HRESULT hr = _CreateOutputResources(outputResources);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("_CreateOutputResources 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT EffectsDrawer::OnColorInfoChanged(
|
||||
const ColorInfo& colorInfo,
|
||||
SmallVectorImpl<winrt::com_ptr<ID3D12Resource>>& outputResources
|
||||
) noexcept {
|
||||
const bool wasScRGB = _isScRGB;
|
||||
HRESULT EffectsDrawer::OnColorInfoChanged(const ColorInfo& colorInfo) noexcept {
|
||||
_isScRGB = colorInfo.kind != winrt::AdvancedColorKind::StandardDynamicRange;
|
||||
|
||||
if (_isScRGB != wasScRGB) {
|
||||
HRESULT hr = _CreateOutputResources(outputResources);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("_CreateOutputResources 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT EffectsDrawer::_CreateOutputResources(
|
||||
SmallVectorImpl<winrt::com_ptr<ID3D12Resource>>& outputResources
|
||||
) noexcept {
|
||||
ID3D12Device5* device = _graphicsContext->GetDevice();
|
||||
|
||||
const uint32_t maxInFlightFrameCount =
|
||||
ScalingWindow::Get().Options().maxProducerInFlightFrames;
|
||||
outputResources.resize(size_t(maxInFlightFrameCount + 1));
|
||||
|
||||
CD3DX12_HEAP_PROPERTIES heapProperties(D3D12_HEAP_TYPE_DEFAULT);
|
||||
|
||||
D3D12_HEAP_FLAGS heapFlag = _graphicsContext->IsHeapFlagCreateNotZeroedSupported() ?
|
||||
D3D12_HEAP_FLAG_CREATE_NOT_ZEROED : D3D12_HEAP_FLAG_NONE;
|
||||
|
||||
CD3DX12_RESOURCE_DESC texDesc = CD3DX12_RESOURCE_DESC::Tex2D(
|
||||
_isScRGB ? DXGI_FORMAT_R16G16B16A16_FLOAT : DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
_outputSize.width,
|
||||
_outputSize.height,
|
||||
1, 1, 1, 0,
|
||||
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS
|
||||
);
|
||||
|
||||
for (winrt::com_ptr<ID3D12Resource>& resource : outputResources) {
|
||||
HRESULT hr = device->CreateCommittedResource(&heapProperties, heapFlag,
|
||||
&texDesc, D3D12_RESOURCE_STATE_COPY_SOURCE, nullptr, IID_PPV_ARGS(&resource));
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("CreateCommittedResource 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,7 @@ public:
|
|||
GraphicsContext& graphicsContext,
|
||||
const ColorInfo& colorInfo,
|
||||
Size inputSize,
|
||||
Size rendererSize,
|
||||
SmallVectorImpl<winrt::com_ptr<ID3D12Resource>>& outputResources
|
||||
Size rendererSize
|
||||
) noexcept;
|
||||
|
||||
HRESULT Draw(
|
||||
|
|
@ -28,21 +27,11 @@ public:
|
|||
return _outputSize;
|
||||
}
|
||||
|
||||
HRESULT OnResized(
|
||||
Size rendererSize,
|
||||
SmallVectorImpl<winrt::com_ptr<ID3D12Resource>>& outputResources
|
||||
) noexcept;
|
||||
HRESULT OnResized(Size rendererSize) noexcept;
|
||||
|
||||
HRESULT OnColorInfoChanged(
|
||||
const ColorInfo& colorInfo,
|
||||
SmallVectorImpl<winrt::com_ptr<ID3D12Resource>>& outputResources
|
||||
) noexcept;
|
||||
HRESULT OnColorInfoChanged(const ColorInfo& colorInfo) noexcept;
|
||||
|
||||
private:
|
||||
HRESULT _CreateOutputResources(
|
||||
SmallVectorImpl<winrt::com_ptr<ID3D12Resource>>& outputResources
|
||||
) noexcept;
|
||||
|
||||
GraphicsContext* _graphicsContext = nullptr;
|
||||
|
||||
Size _inputSize{};
|
||||
|
|
|
|||
|
|
@ -62,8 +62,19 @@ uint64_t FrameProducer::GetLatestFrameNumber() const noexcept {
|
|||
return _frameRingBuffer.GetLatestFrameNumber();
|
||||
}
|
||||
|
||||
bool FrameProducer::ConsumerBeginFrame(ID3D12Resource*& buffer, UINT64& fenceValueToSignal) noexcept {
|
||||
return _frameRingBuffer.ConsumerBeginFrame(buffer, fenceValueToSignal);
|
||||
bool FrameProducer::ConsumerBeginFrame(
|
||||
ID3D12Resource*& buffer,
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE& srvHandle,
|
||||
UINT64& fenceValueToSignal
|
||||
) noexcept {
|
||||
uint32_t bufferIdx;
|
||||
if (!_frameRingBuffer.ConsumerBeginFrame(bufferIdx, buffer, fenceValueToSignal)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& dynamicDescriptorHeap = _graphicsContext.GetDynamicDescriptorHeap();
|
||||
srvHandle = dynamicDescriptorHeap.GetGpuHandle(_outputSrvBaseOffset + bufferIdx);
|
||||
return true;
|
||||
}
|
||||
|
||||
HRESULT FrameProducer::ConsumerEndFrame(
|
||||
|
|
@ -96,16 +107,19 @@ void FrameProducer::OnResizedAsync(
|
|||
return;
|
||||
}
|
||||
|
||||
SmallVector<winrt::com_ptr<ID3D12Resource>, 4> outputResources;
|
||||
hr = _effectsDrawer.OnResized(rendererSize, outputResources);
|
||||
hr = _effectsDrawer.OnResized(rendererSize);
|
||||
if (!_CheckResult(hr, "EffectsDrawer::OnResized 失败")) {
|
||||
return;
|
||||
}
|
||||
|
||||
outputSize = _effectsDrawer.GetOutputSize();
|
||||
|
||||
_frameRingBuffer.UpdateResources(outputResources);
|
||||
_CreateOutputUavs();
|
||||
hr = _frameRingBuffer.OnResized(outputSize);
|
||||
if (!_CheckResult(hr, "FrameRingBuffer::OnResized 失败")) {
|
||||
return;
|
||||
}
|
||||
|
||||
_CreateOutputDescriptors();
|
||||
|
||||
hr = _Render();
|
||||
if (!_CheckResult(hr, "_Render 失败")) {
|
||||
|
|
@ -148,21 +162,16 @@ void FrameProducer::OnColorInfoChangedAsync(
|
|||
return;
|
||||
}
|
||||
|
||||
{
|
||||
_CreateInputSrvs();
|
||||
|
||||
SmallVector<winrt::com_ptr<ID3D12Resource>, 4> outputResources;
|
||||
hr = _effectsDrawer.OnColorInfoChanged(colorInfo, outputResources);
|
||||
if (!_CheckResult(hr, "EffectsDrawer::OnColorInfoChanged 失败")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!outputResources.empty()) {
|
||||
_frameRingBuffer.UpdateResources(outputResources);
|
||||
_CreateOutputUavs();
|
||||
}
|
||||
hr = _effectsDrawer.OnColorInfoChanged(colorInfo);
|
||||
if (!_CheckResult(hr, "EffectsDrawer::OnColorInfoChanged 失败")) {
|
||||
return;
|
||||
}
|
||||
|
||||
_frameRingBuffer.OnColorInfoChanged(colorInfo);
|
||||
|
||||
_CreateInputDescriptors();
|
||||
_CreateOutputDescriptors();
|
||||
|
||||
// 等待新帧
|
||||
while (true) {
|
||||
bool isNewFrameAvailable;
|
||||
|
|
@ -354,17 +363,14 @@ bool FrameProducer::_Initialize(
|
|||
uint32_t(srcRect.bottom - srcRect.top)
|
||||
};
|
||||
|
||||
SmallVector<winrt::com_ptr<ID3D12Resource>, 4> outputResources;
|
||||
|
||||
if (!_effectsDrawer.Initialize(_graphicsContext, colorInfo, inputSize,
|
||||
rendererSize, outputResources)) {
|
||||
if (!_effectsDrawer.Initialize(_graphicsContext, colorInfo, inputSize, rendererSize)) {
|
||||
Logger::Get().Error("EffectsDrawer::Initialize 失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
outputSize = _effectsDrawer.GetOutputSize();
|
||||
|
||||
if (!_frameRingBuffer.Initialize(_graphicsContext, outputResources)) {
|
||||
if (!_frameRingBuffer.Initialize(_graphicsContext, outputSize, colorInfo)) {
|
||||
Logger::Get().Error("初始化 FrameRingBuffer 失败");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -372,20 +378,27 @@ bool FrameProducer::_Initialize(
|
|||
|
||||
{
|
||||
auto& dynamicDescriptorHeap = _graphicsContext.GetDynamicDescriptorHeap();
|
||||
|
||||
HRESULT hr = dynamicDescriptorHeap.Alloc(maxInFlightFrameCount, _inputSrvBaseOffset);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("DynamicDescriptorHeap::Alloc", hr);
|
||||
Logger::Get().ComError("DynamicDescriptorHeap::Alloc 失败", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = dynamicDescriptorHeap.Alloc(maxInFlightFrameCount + 1, _outputUavBaseOffset);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("DynamicDescriptorHeap::Alloc", hr);
|
||||
Logger::Get().ComError("DynamicDescriptorHeap::Alloc 失败", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
_CreateInputSrvs();
|
||||
_CreateOutputUavs();
|
||||
hr = dynamicDescriptorHeap.Alloc(maxInFlightFrameCount + 1, _outputSrvBaseOffset);
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("DynamicDescriptorHeap::Alloc 失败", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
_CreateInputDescriptors();
|
||||
_CreateOutputDescriptors();
|
||||
}
|
||||
|
||||
_monitorThread = std::thread(&FrameProducer::_MonitorThreadProc, this);
|
||||
|
|
@ -406,7 +419,7 @@ bool FrameProducer::_Initialize(
|
|||
return true;
|
||||
}
|
||||
|
||||
void FrameProducer::_CreateInputSrvs() noexcept {
|
||||
void FrameProducer::_CreateInputDescriptors() noexcept {
|
||||
ID3D12Device5* device = _graphicsContext.GetDevice();
|
||||
auto& dynamicDescriptorHeap = _graphicsContext.GetDynamicDescriptorHeap();
|
||||
const uint32_t descriptorSize = dynamicDescriptorHeap.GetDescriptorSize();
|
||||
|
|
@ -424,22 +437,30 @@ void FrameProducer::_CreateInputSrvs() noexcept {
|
|||
}
|
||||
}
|
||||
|
||||
void FrameProducer::_CreateOutputUavs() noexcept {
|
||||
void FrameProducer::_CreateOutputDescriptors() noexcept {
|
||||
ID3D12Device5* device = _graphicsContext.GetDevice();
|
||||
auto& dynamicDescriptorHeap = _graphicsContext.GetDynamicDescriptorHeap();
|
||||
const uint32_t descriptorSize = dynamicDescriptorHeap.GetDescriptorSize();
|
||||
|
||||
CD3DX12_UNORDERED_ACCESS_VIEW_DESC uavDesc = CD3DX12_UNORDERED_ACCESS_VIEW_DESC::Tex2D(
|
||||
_isScRGB ? DXGI_FORMAT_R16G16B16A16_FLOAT : DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||
CD3DX12_SHADER_RESOURCE_VIEW_DESC srvDesc = CD3DX12_SHADER_RESOURCE_VIEW_DESC::Tex2D(
|
||||
_isScRGB ? DXGI_FORMAT_R16G16B16A16_FLOAT : DXGI_FORMAT_R8G8B8A8_UNORM, 1);
|
||||
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE descriptorCpuHandle =
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE uavCpuHandle =
|
||||
dynamicDescriptorHeap.GetCpuHandle(_outputUavBaseOffset);
|
||||
CD3DX12_CPU_DESCRIPTOR_HANDLE srvCpuHandle =
|
||||
dynamicDescriptorHeap.GetCpuHandle(_outputSrvBaseOffset);
|
||||
|
||||
const uint32_t bufferCount = ScalingWindow::Get().Options().maxProducerInFlightFrames + 1;
|
||||
for (uint32_t i = 0; i < bufferCount; ++i) {
|
||||
device->CreateUnorderedAccessView(
|
||||
_frameRingBuffer.GetBuffer(i), nullptr, &uavDesc, descriptorCpuHandle);
|
||||
descriptorCpuHandle.Offset(descriptorSize);
|
||||
ID3D12Resource* buffer = _frameRingBuffer.GetBuffer(i);
|
||||
|
||||
device->CreateUnorderedAccessView(buffer, nullptr, &uavDesc, uavCpuHandle);
|
||||
uavCpuHandle.Offset(descriptorSize);
|
||||
|
||||
device->CreateShaderResourceView(buffer, &srvDesc, srvCpuHandle);
|
||||
srvCpuHandle.Offset(descriptorSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -481,7 +502,7 @@ HRESULT FrameProducer::_Render() noexcept {
|
|||
CD3DX12_RESOURCE_BARRIER::Transition(
|
||||
input, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, 0),
|
||||
CD3DX12_RESOURCE_BARRIER::Transition(
|
||||
output, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, 0)
|
||||
output, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, 0)
|
||||
};
|
||||
commandList->ResourceBarrier((UINT)std::size(barriers), barriers);
|
||||
}
|
||||
|
|
@ -503,7 +524,7 @@ HRESULT FrameProducer::_Render() noexcept {
|
|||
CD3DX12_RESOURCE_BARRIER::Transition(
|
||||
input, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COMMON, 0),
|
||||
CD3DX12_RESOURCE_BARRIER::Transition(
|
||||
output, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE, 0)
|
||||
output, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COMMON, 0)
|
||||
};
|
||||
commandList->ResourceBarrier((UINT)std::size(barriers), barriers);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public:
|
|||
|
||||
uint64_t GetLatestFrameNumber() const noexcept;
|
||||
|
||||
bool ConsumerBeginFrame(ID3D12Resource*& buffer, UINT64& fenceValueToSignal) noexcept;
|
||||
bool ConsumerBeginFrame(ID3D12Resource*& buffer, D3D12_GPU_DESCRIPTOR_HANDLE& srvHandle, UINT64& fenceValueToSignal) noexcept;
|
||||
|
||||
HRESULT ConsumerEndFrame(
|
||||
ID3D12CommandQueue* commandQueue,
|
||||
|
|
@ -62,9 +62,9 @@ private:
|
|||
Size& outputSize
|
||||
) noexcept;
|
||||
|
||||
void _CreateInputSrvs() noexcept;
|
||||
void _CreateInputDescriptors() noexcept;
|
||||
|
||||
void _CreateOutputUavs() noexcept;
|
||||
void _CreateOutputDescriptors() noexcept;
|
||||
|
||||
HRESULT _Render() noexcept;
|
||||
|
||||
|
|
@ -87,6 +87,7 @@ private:
|
|||
|
||||
uint32_t _inputSrvBaseOffset = 0;
|
||||
uint32_t _outputUavBaseOffset = 0;
|
||||
uint32_t _outputSrvBaseOffset = 0;
|
||||
|
||||
bool _isScRGB = false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,13 +9,15 @@ namespace Magpie {
|
|||
|
||||
bool FrameRingBuffer::Initialize(
|
||||
GraphicsContext& graphicsContext,
|
||||
SmallVectorImpl<winrt::com_ptr<ID3D12Resource>>& resources
|
||||
Size size,
|
||||
const ColorInfo& colorInfo
|
||||
) noexcept {
|
||||
_graphicsContext = &graphicsContext;
|
||||
_size = size;
|
||||
_isScRGB = colorInfo.kind != winrt::AdvancedColorKind::StandardDynamicRange;
|
||||
|
||||
const uint32_t slotCount = ScalingWindow::Get().Options().maxProducerInFlightFrames + 1;
|
||||
_slots.resize(slotCount);
|
||||
assert((uint32_t)resources.size() == slotCount);
|
||||
|
||||
// 消费者应落后于生产者
|
||||
_curConsumerIdx = slotCount - 1;
|
||||
|
|
@ -34,7 +36,11 @@ bool FrameRingBuffer::Initialize(
|
|||
return false;
|
||||
}
|
||||
|
||||
UpdateResources(resources);
|
||||
hr = _CreateBuffers();
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("_CreateBuffers 失败", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -112,7 +118,11 @@ HRESULT FrameRingBuffer::ProducerEndFrame(ID3D12CommandQueue* commandQueue) noex
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
bool FrameRingBuffer::ConsumerBeginFrame(ID3D12Resource*& buffer, UINT64& fenceValueToSignal) noexcept {
|
||||
bool FrameRingBuffer::ConsumerBeginFrame(
|
||||
uint32_t& bufferIdx,
|
||||
ID3D12Resource*& buffer,
|
||||
UINT64& fenceValueToSignal
|
||||
) noexcept {
|
||||
auto lk = _lock.lock_exclusive();
|
||||
|
||||
if (_curConsumerIdx != _curProducerIdx) {
|
||||
|
|
@ -148,6 +158,7 @@ bool FrameRingBuffer::ConsumerBeginFrame(ID3D12Resource*& buffer, UINT64& fenceV
|
|||
fenceValueToSignal = ++_curConsumerFenceValue;
|
||||
curSlot.consumerFenceValue = fenceValueToSignal;
|
||||
|
||||
bufferIdx = _curConsumerIdx;
|
||||
buffer = curSlot.resource.get();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -191,13 +202,61 @@ uint64_t FrameRingBuffer::GetLatestFrameNumber() const noexcept {
|
|||
return _producerFence->GetCompletedValue();
|
||||
}
|
||||
|
||||
void FrameRingBuffer::UpdateResources(
|
||||
SmallVectorImpl<winrt::com_ptr<ID3D12Resource>>& resources
|
||||
) noexcept {
|
||||
const size_t slotCount = _slots.size();
|
||||
for (size_t i = 0; i < slotCount; ++i) {
|
||||
_slots[i].resource = std::move(resources[i]);
|
||||
HRESULT FrameRingBuffer::OnResized(Size size) noexcept {
|
||||
_size = size;
|
||||
|
||||
HRESULT hr = _CreateBuffers();
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("_CreateBuffers 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT FrameRingBuffer::OnColorInfoChanged(const ColorInfo& colorInfo) noexcept {
|
||||
const bool wasScRGB = _isScRGB;
|
||||
_isScRGB = colorInfo.kind != winrt::AdvancedColorKind::StandardDynamicRange;
|
||||
|
||||
if (_isScRGB == wasScRGB) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT hr = _CreateBuffers();
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("_CreateBuffers 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT FrameRingBuffer::_CreateBuffers() noexcept {
|
||||
ID3D12Device5* device = _graphicsContext->GetDevice();
|
||||
|
||||
CD3DX12_HEAP_PROPERTIES heapProperties(D3D12_HEAP_TYPE_DEFAULT);
|
||||
|
||||
D3D12_HEAP_FLAGS heapFlag = _graphicsContext->IsHeapFlagCreateNotZeroedSupported() ?
|
||||
D3D12_HEAP_FLAG_CREATE_NOT_ZEROED : D3D12_HEAP_FLAG_NONE;
|
||||
|
||||
CD3DX12_RESOURCE_DESC texDesc = CD3DX12_RESOURCE_DESC::Tex2D(
|
||||
_isScRGB ? DXGI_FORMAT_R16G16B16A16_FLOAT : DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
_size.width,
|
||||
_size.height,
|
||||
1, 1, 1, 0,
|
||||
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS
|
||||
);
|
||||
|
||||
for (_FrameResourceSlot& slot : _slots) {
|
||||
HRESULT hr = device->CreateCommittedResource(&heapProperties, heapFlag,
|
||||
&texDesc, D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(&slot.resource));
|
||||
if (FAILED(hr)) {
|
||||
Logger::Get().ComError("CreateCommittedResource 失败", hr);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ public:
|
|||
|
||||
bool Initialize(
|
||||
GraphicsContext& graphicsContext,
|
||||
SmallVectorImpl<winrt::com_ptr<ID3D12Resource>>& resources
|
||||
Size size,
|
||||
const ColorInfo& colorInfo
|
||||
) noexcept;
|
||||
|
||||
ID3D12Resource* GetBuffer(uint32_t index) noexcept;
|
||||
|
|
@ -22,7 +23,7 @@ public:
|
|||
|
||||
HRESULT ProducerEndFrame(ID3D12CommandQueue* commandQueue) noexcept;
|
||||
|
||||
bool ConsumerBeginFrame(ID3D12Resource*& buffer, UINT64& fenceValueToSignal) noexcept;
|
||||
bool ConsumerBeginFrame(uint32_t& bufferIdx, ID3D12Resource*& buffer, UINT64& fenceValueToSignal) noexcept;
|
||||
|
||||
HRESULT ConsumerEndFrame(
|
||||
ID3D12CommandQueue* commandQueue,
|
||||
|
|
@ -33,9 +34,13 @@ public:
|
|||
|
||||
uint64_t GetLatestFrameNumber() const noexcept;
|
||||
|
||||
void UpdateResources(SmallVectorImpl<winrt::com_ptr<ID3D12Resource>>& resources) noexcept;
|
||||
HRESULT OnResized(Size size) noexcept;
|
||||
|
||||
HRESULT OnColorInfoChanged(const ColorInfo& colorInfo) noexcept;
|
||||
|
||||
private:
|
||||
HRESULT _CreateBuffers() noexcept;
|
||||
|
||||
// 只在生产者线程访问
|
||||
GraphicsContext* _graphicsContext = nullptr;
|
||||
|
||||
|
|
@ -58,6 +63,9 @@ private:
|
|||
winrt::com_ptr<ID3D12Fence1> _consumerFence;
|
||||
uint64_t _curConsumerFenceValue = 0;
|
||||
winrt::com_ptr<ID3D12Fence1> _producerFence;
|
||||
|
||||
Size _size{};
|
||||
bool _isScRGB = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -494,10 +494,11 @@ HRESULT Renderer2::_UpdateColorSpace() noexcept {
|
|||
}
|
||||
|
||||
HRESULT Renderer2::_RenderImpl(bool waitForGpu) noexcept {
|
||||
// 处于 COPY_SOURCE 状态,使用结束后也应处于此状态
|
||||
// 处于 COMMON 状态,依赖隐式状态转换
|
||||
ID3D12Resource* curBuffer;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE srvHandle;
|
||||
UINT64 fenceValueToSignal;
|
||||
if (!_frameProducer.ConsumerBeginFrame(curBuffer, fenceValueToSignal)) {
|
||||
if (!_frameProducer.ConsumerBeginFrame(curBuffer, srvHandle, fenceValueToSignal)) {
|
||||
// 不应出现第一帧未完成的情况
|
||||
assert(false);
|
||||
return S_OK;
|
||||
|
|
@ -518,8 +519,13 @@ HRESULT Renderer2::_RenderImpl(bool waitForGpu) noexcept {
|
|||
|
||||
ID3D12GraphicsCommandList* commandList = _graphicsContext.GetCommandList();
|
||||
|
||||
/*commandList->SetGraphicsRootSignature(_rootSignature.get());
|
||||
commandList->SetGraphicsRootDescriptorTable(1, );
|
||||
{
|
||||
ID3D12DescriptorHeap* t = _graphicsContext.GetDynamicDescriptorHeap().GetHeap();
|
||||
commandList->SetDescriptorHeaps(1, &t);
|
||||
}
|
||||
|
||||
commandList->SetGraphicsRootSignature(_rootSignature.get());
|
||||
commandList->SetGraphicsRootDescriptorTable(1, srvHandle);
|
||||
|
||||
{
|
||||
CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(
|
||||
|
|
@ -541,80 +547,7 @@ HRESULT Renderer2::_RenderImpl(bool waitForGpu) noexcept {
|
|||
commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr);
|
||||
|
||||
commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
commandList->DrawInstanced(3, 1, 0, 0);*/
|
||||
|
||||
if (Size size = _presenter->GetSize(); _outputRect == Rect{ 0,0,size.width,size.height }) {
|
||||
{
|
||||
CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(
|
||||
frameTex, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_COPY_DEST, 0);
|
||||
commandList->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
|
||||
commandList->CopyResource(frameTex, curBuffer);
|
||||
} else {
|
||||
{
|
||||
D3D12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(
|
||||
frameTex, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET, 0);
|
||||
commandList->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
|
||||
// 存在黑边时应填充背景。使用交换链呈现时需要这个操作,因为我们指定了
|
||||
// DXGI_SWAP_EFFECT_FLIP_DISCARD,同时也是为了和 RTSS 兼容。
|
||||
{
|
||||
SmallVector<D3D12_RECT, 4> rects;
|
||||
if (_outputRect.left > 0) {
|
||||
rects.push_back({
|
||||
0,
|
||||
0,
|
||||
(LONG)_outputRect.left,
|
||||
(LONG)size.height
|
||||
});
|
||||
}
|
||||
if (_outputRect.top > 0) {
|
||||
rects.push_back({
|
||||
(LONG)_outputRect.left,
|
||||
0,
|
||||
(LONG)_outputRect.right,
|
||||
(LONG)_outputRect.top
|
||||
});
|
||||
}
|
||||
if (_outputRect.right < size.width) {
|
||||
rects.push_back({
|
||||
(LONG)_outputRect.right,
|
||||
0,
|
||||
(LONG)size.width,
|
||||
(LONG)size.height
|
||||
});
|
||||
}
|
||||
if (_outputRect.bottom < size.height) {
|
||||
rects.push_back({
|
||||
(LONG)_outputRect.left,
|
||||
(LONG)_outputRect.bottom,
|
||||
(LONG)_outputRect.right,
|
||||
(LONG)size.height
|
||||
});
|
||||
}
|
||||
|
||||
static constexpr FLOAT BLACK[4] = { 0.0f,0.0f,0.0f,1.0f };
|
||||
commandList->ClearRenderTargetView(rtvHandle, BLACK, (UINT)rects.size(), rects.data());
|
||||
}
|
||||
|
||||
{
|
||||
CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(
|
||||
frameTex, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_DEST, 0);
|
||||
commandList->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
|
||||
CD3DX12_TEXTURE_COPY_LOCATION src(curBuffer, 0);
|
||||
CD3DX12_TEXTURE_COPY_LOCATION dest(frameTex, 0);
|
||||
commandList->CopyTextureRegion(&dest, _outputRect.left, _outputRect.top, 0, &src, nullptr);
|
||||
}
|
||||
|
||||
{
|
||||
CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(
|
||||
frameTex, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_RENDER_TARGET, 0);
|
||||
commandList->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
commandList->DrawInstanced(3, 1, 0, 0);
|
||||
|
||||
hr = _cursorDrawer.Draw();
|
||||
if (FAILED(hr)) {
|
||||
|
|
|
|||
|
|
@ -812,8 +812,8 @@
|
|||
<Import Project="..\..\packages\Microsoft.UI.Xaml.2.8.7\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\packages\Microsoft.UI.Xaml.2.8.7\build\native\Microsoft.UI.Xaml.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.Direct3D.D3D12.1.618.5\build\native\Microsoft.Direct3D.D3D12.targets" Condition="Exists('..\..\packages\Microsoft.Direct3D.D3D12.1.618.5\build\native\Microsoft.Direct3D.D3D12.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.Web.WebView2.1.0.3719.77\build\native\Microsoft.Web.WebView2.targets" Condition="Exists('..\..\packages\Microsoft.Web.WebView2.1.0.3719.77\build\native\Microsoft.Web.WebView2.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.Web.WebView2.1.0.3800.47\build\native\Microsoft.Web.WebView2.targets" Condition="Exists('..\..\packages\Microsoft.Web.WebView2.1.0.3800.47\build\native\Microsoft.Web.WebView2.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
|
|
@ -825,11 +825,11 @@
|
|||
<Error Condition="!Exists('..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Direct3D.D3D12.1.618.5\build\native\Microsoft.Direct3D.D3D12.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Direct3D.D3D12.1.618.5\build\native\Microsoft.Direct3D.D3D12.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Direct3D.D3D12.1.618.5\build\native\Microsoft.Direct3D.D3D12.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Direct3D.D3D12.1.618.5\build\native\Microsoft.Direct3D.D3D12.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Web.WebView2.1.0.3719.77\build\native\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Web.WebView2.1.0.3719.77\build\native\Microsoft.Web.WebView2.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.260126.7\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Web.WebView2.1.0.3800.47\build\native\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Web.WebView2.1.0.3800.47\build\native\Microsoft.Web.WebView2.targets'))" />
|
||||
</Target>
|
||||
<!-- 防止生成的 winmd 被复制到输出文件夹 -->
|
||||
<PropertyGroup Condition="!$(IsPackaged)">
|
||||
<CppWinRTProjectWinMD>$(CppWinRTMergedDir)\$(RootNamespace).winmd</CppWinRTProjectWinMD>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
<packages>
|
||||
<package id="Microsoft.Direct3D.D3D12" version="1.618.5" targetFramework="native" />
|
||||
<package id="Microsoft.UI.Xaml" version="2.8.7" targetFramework="native" />
|
||||
<package id="Microsoft.Web.WebView2" version="1.0.3719.77" targetFramework="native" />
|
||||
<package id="Microsoft.Web.WebView2" version="1.0.3800.47" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.250303.1" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.260126.7" targetFramework="native" />
|
||||
</packages>
|
||||
</packages>
|
||||
Loading…
Add table
Add a link
Reference in a new issue