Ошибка выполнения DirectX12 commandList

Я начал изучать DirectX12 и пытаюсь создать какой-то простой движок.
Я следую Фрэнку Д. Луне «Введение в 3D-программирование с DirectX12», и у меня есть некоторые проблемы.
Сначала при создании swapChain, заполняя описание так:

DXGI_SWAP_CHAIN_DESC swapChainDesc;
swapChainDesc.BufferDesc.Width = Core::displayWidth;
swapChainDesc.BufferDesc.Height = Core::displayHeight;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferDesc.Format = Core::pixelDefinitionFormat;
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
swapChainDesc.SampleDesc.Count = Core::multiSamplingLevel ? 4 : 1;
swapChainDesc.SampleDesc.Quality = Core::multiSamplingEnabled ? (Core::multiSamplingLevel - 1) : 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = (INT) Core::buffering;
swapChainDesc.OutputWindow = Core::mainWindow;
swapChainDesc.Windowed = true;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

// Note: Swap chain uses queue to perform flush.
ThrowIfFailed(Core::factory->CreateSwapChain(
Core::commandQueue.Get(),
&swapChainDesc,
Core::swapChain.GetAddressOf()
));

Я получаю ошибку «плохой параметр». Я уже нашел решение на MSDN, но я хочу знать, что я делаю неправильно.

Второй вопрос: почему я:

D3D12 ERROR: ID3D12GraphicsCommandList::*: A single command list cannot write to multiple buffers within a particular swapchain. [ STATE_SETTING ERROR #904: COMMAND_LIST_MULTIPLE_SWAPCHAIN_BUFFER_REFERENCES]

Во время выполнения этого фрагмента кода очистки экрана:

void Renderer::drawSomething() {

// Reuse the memory associated with command recording.
// We can only reset when the associated command lists have finished
// execution on the GPU.
ThrowIfFailed(Core::commandAllocator->Reset());

// A command list can be reset after it has been added to the
// command queue via ExecuteCommandList. Reusing the command list reuses memory.
ThrowIfFailed(Core::commandList->Reset(Core::commandAllocator.Get(), NULL));

// Set the viewport and scissor rect. This needs to be reset
// whenever the command list is reset.
Core::commandList->RSSetViewports(1, &Core::viewport);
Core::commandList->RSSetScissorRects(1, &Core::scissorsRectangle);

// Indicate a state transition on the resource usage.
Core::commandList->ResourceBarrier(
1,
&CD3DX12_RESOURCE_BARRIER::Transition(
Core::getCurrentBackBuffer().Get(),
D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_PRESENT,
D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_RENDER_TARGET
)
);// Specify the buffers we are going to render to.
Core::commandList->OMSetRenderTargets(
1,
&Core::getCurrentBackBufferView(),
true,
&Core::getDSVHeapStartDescriptorHandle()
);

// Clear the back buffer and depth buffer.
Core::commandList->ClearRenderTargetView(
Core::getCurrentBackBufferView(),
DirectX::Colors::LightSteelBlue,
0,
NULL
);

Core::commandList->ClearDepthStencilView(
Core::getDSVHeapStartDescriptorHandle(),
D3D12_CLEAR_FLAGS::D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAGS::D3D12_CLEAR_FLAG_STENCIL,
1.0f,
0,
0,
NULL
);//// Indicate a state transition on the resource usage.
Core::commandList->ResourceBarrier(
1,
&CD3DX12_RESOURCE_BARRIER::Transition(
Core::getCurrentBackBuffer().Get(),
D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_RENDER_TARGET,
D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_PRESENT
)
);

// Done recording commands.
ThrowIfFailed(Core::commandList->Close());

// Add the command list to the queue for execution.
ID3D12CommandList* cmdsLists[] = {Core::commandList.Get()};
Core::commandQueue->ExecuteCommandLists(_countof(cmdsLists), cmdsLists);

// swap the back and front buffers
ThrowIfFailed(Core::swapChain->Present(0, 0));
UINT buffering = Core::buffering;
Core::currentBackBuffer = (Core::currentBackBuffer + 1) % buffering;
Core::flushCommandQueue();
}

Чтобы не создавать большой беспорядок в этом посте, я не буду помещать здесь весь код, но если вы хотите посмотреть, как он выглядит, или это будет важно, в этом случае весь мой репозиторий находится здесь:
хранилище

Он очень маленький и простой, почти весь код помещен в класс Core.

Заранее спасибо!

Редактировать:
Я нашел решение второго вопроса.
Проблема была в этом цикле:

void Core::createSwapChainBuffersIntoRTVHeap() {
for (UINT i = 0; i < Core::buffering; i++) {
CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHeapHandle(rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
ErrorUtils::messageAndExitIfFailed(
swapChain->GetBuffer(i, IID_PPV_ARGS(&swapChainBackBuffers[i])),
L"B³¹d pobierania backBuffera!",
GET_SWAPCHAIN_BACK_BUFFER_ERROR
);

device->CreateRenderTargetView(swapChainBackBuffers[i].Get(), NULL, rtvHeapHandle);
//Zapamiêtuje offset, to jest sterta po prostu zwyk³a
rtvHeapHandle.Offset(1, rtvDescriptorSize);
}

}

Я сделал только один шаг, чтобы этот код выглядел так:

void Core::createSwapChainBuffersIntoRTVHeap() {
CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHeapHandle(rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
for (UINT i = 0; i < Core::buffering; i++) {
ErrorUtils::messageAndExitIfFailed(
swapChain->GetBuffer(i, IID_PPV_ARGS(&swapChainBackBuffers[i])),
L"B³¹d pobierania backBuffera!",
GET_SWAPCHAIN_BACK_BUFFER_ERROR
);

device->CreateRenderTargetView(swapChainBackBuffers[i].Get(), NULL, rtvHeapHandle);
//Zapamiêtuje offset, to jest sterta po prostu zwyk³a
rtvHeapHandle.Offset(1, rtvDescriptorSize);
}

}

После этого. Когда закрытие командной строки прошло правильно, я получил AccessViolationException в D3D12.dll на:

ThrowIfFailed(Core::swapChain->Present(0, 0));

Что после нескольких часов интернет-исследований я исправил, форсируя WARP в этом приложении, используя «dxcpl.exe».
Я предполагаю, что это потому, что я работаю на ноутбуке с HD4000 и Nvidia в качестве второй карты, но я не уверен.

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector