D3D12 vertex and index buffers with resource transitions

This commit is contained in:
Austin Eng 2017-06-09 12:50:51 -04:00 committed by Austin Eng
parent 459537491b
commit d251356783
11 changed files with 561 additions and 177 deletions

View File

@ -216,10 +216,14 @@ if (WIN32)
SetPIC(d3d12_autogen)
list(APPEND BACKEND_SOURCES
${D3D12_DIR}/BufferD3D12.cpp
${D3D12_DIR}/BufferD3D12.h
${D3D12_DIR}/CommandBufferD3D12.cpp
${D3D12_DIR}/CommandBufferD3D12.h
${D3D12_DIR}/D3D12Backend.cpp
${D3D12_DIR}/D3D12Backend.h
${D3D12_DIR}/InputStateD3D12.cpp
${D3D12_DIR}/InputStateD3D12.h
${D3D12_DIR}/PipelineD3D12.cpp
${D3D12_DIR}/PipelineD3D12.h
${D3D12_DIR}/PipelineLayoutD3D12.cpp

View File

@ -0,0 +1,163 @@
// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "BufferD3D12.h"
#include "D3D12Backend.h"
namespace backend {
namespace d3d12 {
namespace {
D3D12_RESOURCE_STATES D3D12BufferUsage(nxt::BufferUsageBit usage) {
D3D12_RESOURCE_STATES resourceState = D3D12_RESOURCE_STATE_COMMON;
if (usage & nxt::BufferUsageBit::TransferSrc) {
resourceState |= D3D12_RESOURCE_STATE_COPY_SOURCE;
}
if (usage & nxt::BufferUsageBit::TransferDst) {
resourceState |= D3D12_RESOURCE_STATE_COPY_DEST;
}
if (usage & (nxt::BufferUsageBit::Vertex | nxt::BufferUsageBit::Uniform)) {
resourceState |= D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
}
if (usage & nxt::BufferUsageBit::Index) {
resourceState |= D3D12_RESOURCE_STATE_INDEX_BUFFER;
}
if (usage & nxt::BufferUsageBit::Storage) {
resourceState |= D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
}
return resourceState;
}
}
Buffer::Buffer(Device* device, BufferBuilder* builder)
: BufferBase(builder), device(device) {
D3D12_RESOURCE_DESC resourceDescriptor;
resourceDescriptor.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
resourceDescriptor.Alignment = 0;
resourceDescriptor.Width = GetSize();
resourceDescriptor.Height = 1;
resourceDescriptor.DepthOrArraySize = 1;
resourceDescriptor.MipLevels = 1;
resourceDescriptor.Format = DXGI_FORMAT_UNKNOWN;
resourceDescriptor.SampleDesc.Count = 1;
resourceDescriptor.SampleDesc.Quality = 0;
resourceDescriptor.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
resourceDescriptor.Flags = D3D12_RESOURCE_FLAG_NONE;
{
D3D12_HEAP_PROPERTIES heapProperties;
heapProperties.Type = D3D12_HEAP_TYPE_UPLOAD;
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
heapProperties.CreationNodeMask = 0;
heapProperties.VisibleNodeMask = 0;
ASSERT_SUCCESS(device->GetD3D12Device()->CreateCommittedResource(
&heapProperties,
D3D12_HEAP_FLAG_NONE,
&resourceDescriptor,
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(&uploadResource)
));
}
{
D3D12_HEAP_PROPERTIES heapProperties;
heapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
heapProperties.CreationNodeMask = 0;
heapProperties.VisibleNodeMask = 0;
ASSERT_SUCCESS(device->GetD3D12Device()->CreateCommittedResource(
&heapProperties,
D3D12_HEAP_FLAG_NONE,
&resourceDescriptor,
D3D12BufferUsage(GetUsage()),
nullptr,
IID_PPV_ARGS(&resource)
));
}
}
ComPtr<ID3D12Resource> Buffer::GetD3D12Resource() {
return resource;
}
bool Buffer::GetResourceTransitionBarrier(nxt::BufferUsageBit currentUsage, nxt::BufferUsageBit targetUsage, D3D12_RESOURCE_BARRIER* barrier) {
D3D12_RESOURCE_STATES stateBefore = D3D12BufferUsage(currentUsage);
D3D12_RESOURCE_STATES stateAfter = D3D12BufferUsage(targetUsage);
if (stateBefore == stateAfter) {
return false;
}
barrier->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier->Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
barrier->Transition.pResource = resource.Get();
barrier->Transition.StateBefore = stateBefore;
barrier->Transition.StateAfter = stateAfter;
barrier->Transition.Subresource = 0;
return true;
}
D3D12_GPU_VIRTUAL_ADDRESS Buffer::GetVA() const {
return resource->GetGPUVirtualAddress();
}
void Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) {
uint32_t begin = start * sizeof(uint32_t);
uint32_t end = (start + count) * sizeof(uint32_t);
uint8_t* mappedResource = nullptr;
D3D12_RANGE readRange;
readRange.Begin = 0;
readRange.End = 0;
ASSERT_SUCCESS(uploadResource->Map(0, &readRange, reinterpret_cast<void**>(&mappedResource)));
memcpy(&mappedResource[begin], data, end - begin);
D3D12_RANGE writeRange;
writeRange.Begin = begin;
writeRange.End = end;
uploadResource->Unmap(0, &writeRange);
device->GetPendingCommandList()->CopyBufferRegion(resource.Get(), begin, uploadResource.Get(), begin, end - begin);
}
void Buffer::MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) {
// TODO(cwallez@chromium.org): Implement Map Read for the null backend
}
void Buffer::UnmapImpl() {
// TODO(cwallez@chromium.org): Implement Map Read for the null backend
}
void Buffer::TransitionUsageImpl(nxt::BufferUsageBit currentUsage, nxt::BufferUsageBit targetUsage) {
D3D12_RESOURCE_BARRIER barrier;
if (GetResourceTransitionBarrier(currentUsage, targetUsage, &barrier)) {
device->GetPendingCommandList()->ResourceBarrier(1, &barrier);
}
}
}
}

View File

@ -0,0 +1,51 @@
// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BACKEND_D3D12_BUFFERD3D12_H_
#define BACKEND_D3D12_BUFFERD3D12_H_
#include "common/Buffer.h"
#include "d3d12_platform.h"
namespace backend {
namespace d3d12 {
class Device;
class Buffer : public BufferBase {
public:
Buffer(Device* device, BufferBuilder* builder);
ComPtr<ID3D12Resource> GetD3D12Resource();
D3D12_GPU_VIRTUAL_ADDRESS GetVA() const;
bool GetResourceTransitionBarrier(nxt::BufferUsageBit currentUsage, nxt::BufferUsageBit targetUsage, D3D12_RESOURCE_BARRIER* barrier);
private:
Device* device;
ComPtr<ID3D12Resource> uploadResource;
ComPtr<ID3D12Resource> resource;
// NXT API
void SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) override;
void MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) override;
void UnmapImpl() override;
void TransitionUsageImpl(nxt::BufferUsageBit currentUsage, nxt::BufferUsageBit targetUsage) override;
};
}
}
#endif // BACKEND_D3D12_BUFFERD3D12_H_

View File

@ -16,12 +16,25 @@
#include "common/Commands.h"
#include "D3D12Backend.h"
#include "BufferD3D12.h"
#include "InputStateD3D12.h"
#include "PipelineD3D12.h"
#include "PipelineLayoutD3D12.h"
namespace backend {
namespace d3d12 {
namespace {
DXGI_FORMAT DXGIIndexFormat(nxt::IndexFormat format) {
switch (format) {
case nxt::IndexFormat::Uint16:
return DXGI_FORMAT_R16_UINT;
case nxt::IndexFormat::Uint32:
return DXGI_FORMAT_R32_UINT;
}
}
}
CommandBuffer::CommandBuffer(Device* device, CommandBufferBuilder* builder)
: CommandBufferBase(builder), device(device), commands(builder->AcquireCommands()) {
}
@ -60,7 +73,6 @@ namespace d3d12 {
commandList->OMSetRenderTargets(1, &device->GetCurrentRenderTargetDescriptor(), FALSE, nullptr);
}
break;
case Command::CopyBufferToBuffer:
{
CopyBufferToBufferCmd* copy = commands.NextCommand<CopyBufferToBufferCmd>();
@ -99,6 +111,15 @@ namespace d3d12 {
case Command::DrawElements:
{
DrawElementsCmd* draw = commands.NextCommand<DrawElementsCmd>();
commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
commandList->DrawIndexedInstanced(
draw->indexCount,
draw->instanceCount,
draw->firstIndex,
0,
draw->firstInstance
);
}
break;
@ -144,24 +165,59 @@ namespace d3d12 {
case Command::SetIndexBuffer:
{
SetIndexBufferCmd* cmd = commands.NextCommand<SetIndexBufferCmd>();
Buffer* buffer = ToBackend(cmd->buffer.Get());
D3D12_INDEX_BUFFER_VIEW bufferView;
bufferView.BufferLocation = buffer->GetVA() + cmd->offset;
bufferView.SizeInBytes = buffer->GetSize() - cmd->offset;
bufferView.Format = DXGIIndexFormat(cmd->format);
commandList->IASetIndexBuffer(&bufferView);
}
break;
case Command::SetVertexBuffers:
{
SetVertexBuffersCmd* cmd = commands.NextCommand<SetVertexBuffersCmd>();
auto buffers = commands.NextData<Ref<BufferBase>>(cmd->count);
auto offsets = commands.NextData<uint32_t>(cmd->count);
auto inputState = ToBackend(lastPipeline->GetInputState());
std::array<D3D12_VERTEX_BUFFER_VIEW, kMaxVertexInputs> d3d12BufferViews;
for (uint32_t i = 0; i < cmd->count; ++i) {
auto input = inputState->GetInput(cmd->startSlot + i);
Buffer* buffer = ToBackend(buffers[i].Get());
d3d12BufferViews[i].BufferLocation = buffer->GetVA() + offsets[i];
d3d12BufferViews[i].StrideInBytes = input.stride;
d3d12BufferViews[i].SizeInBytes = buffer->GetSize() - offsets[i];
}
commandList->IASetVertexBuffers(cmd->startSlot, cmd->count, d3d12BufferViews.data());
}
break;
case Command::TransitionBufferUsage:
{
TransitionBufferUsageCmd* cmd = commands.NextCommand<TransitionBufferUsageCmd>();
Buffer* buffer = ToBackend(cmd->buffer.Get());
D3D12_RESOURCE_BARRIER barrier;
if (buffer->GetResourceTransitionBarrier(buffer->GetUsage(), cmd->usage, &barrier)) {
commandList->ResourceBarrier(1, &barrier);
}
buffer->UpdateUsageInternal(cmd->usage);
}
break;
case Command::TransitionTextureUsage:
{
TransitionTextureUsageCmd* cmd = commands.NextCommand<TransitionTextureUsageCmd>();
Texture* texture = ToBackend(cmd->texture.Get());
texture->UpdateUsageInternal(cmd->usage);
}
break;
}

View File

@ -14,7 +14,9 @@
#include "D3D12Backend.h"
#include "BufferD3D12.h"
#include "CommandBufferD3D12.h"
#include "InputStateD3D12.h"
#include "PipelineD3D12.h"
#include "PipelineLayoutD3D12.h"
#include "QueueD3D12.h"
@ -51,6 +53,15 @@ namespace d3d12 {
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
ASSERT_SUCCESS(d3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&commandQueue)));
ASSERT_SUCCESS(d3d12Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&pendingCommandAllocator)));
ASSERT_SUCCESS(d3d12Device->CreateCommandList(
0,
D3D12_COMMAND_LIST_TYPE_DIRECT,
pendingCommandAllocator.Get(),
nullptr,
IID_PPV_ARGS(&pendingCommandList)
));
}
Device::~Device() {
@ -64,6 +75,14 @@ namespace d3d12 {
return commandQueue;
}
ComPtr<ID3D12CommandAllocator> Device::GetPendingCommandAllocator() {
return pendingCommandAllocator;
}
ComPtr<ID3D12GraphicsCommandList> Device::GetPendingCommandList() {
return pendingCommandList;
}
D3D12_CPU_DESCRIPTOR_HANDLE Device::GetCurrentRenderTargetDescriptor() {
return renderTargetDescriptor;
}
@ -139,26 +158,6 @@ namespace d3d12 {
: BindGroupLayoutBase(builder), device(device) {
}
// Buffer
Buffer::Buffer(Device* device, BufferBuilder* builder)
: BufferBase(builder), device(device) {
}
void Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) {
}
void Buffer::MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) {
// TODO(cwallez@chromium.org): Implement Map Read for the null backend
}
void Buffer::UnmapImpl() {
// TODO(cwallez@chromium.org): Implement Map Read for the null backend
}
void Buffer::TransitionUsageImpl(nxt::BufferUsageBit currentUsage, nxt::BufferUsageBit targetUsage) {
}
// BufferView
BufferView::BufferView(Device* device, BufferViewBuilder* builder)
@ -177,12 +176,6 @@ namespace d3d12 {
: FramebufferBase(builder), device(device) {
}
// InputState
InputState::InputState(Device* device, InputStateBuilder * builder)
: InputStateBase(builder), device(device) {
}
// RenderPass
RenderPass::RenderPass(Device* device, RenderPassBuilder* builder)

View File

@ -106,6 +106,8 @@ namespace d3d12 {
ComPtr<ID3D12Device> GetD3D12Device();
ComPtr<ID3D12CommandQueue> GetCommandQueue();
ComPtr<ID3D12CommandAllocator> GetPendingCommandAllocator();
ComPtr<ID3D12GraphicsCommandList> GetPendingCommandList();
D3D12_CPU_DESCRIPTOR_HANDLE GetCurrentRenderTargetDescriptor();
void SetNextRenderTargetDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE renderTargetDescriptor);
@ -117,6 +119,8 @@ namespace d3d12 {
private:
ComPtr<ID3D12Device> d3d12Device;
ComPtr<ID3D12CommandQueue> commandQueue;
ComPtr<ID3D12CommandAllocator> pendingCommandAllocator;
ComPtr<ID3D12GraphicsCommandList> pendingCommandList;
D3D12_CPU_DESCRIPTOR_HANDLE renderTargetDescriptor;
};
@ -137,19 +141,6 @@ namespace d3d12 {
Device* device;
};
class Buffer : public BufferBase {
public:
Buffer(Device* device, BufferBuilder* builder);
private:
void SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) override;
void MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) override;
void UnmapImpl() override;
void TransitionUsageImpl(nxt::BufferUsageBit currentUsage, nxt::BufferUsageBit targetUsage) override;
Device* device;
};
class BufferView : public BufferViewBase {
public:
BufferView(Device* device, BufferViewBuilder* builder);
@ -174,14 +165,6 @@ namespace d3d12 {
Device* device;
};
class InputState : public InputStateBase {
public:
InputState(Device* device, InputStateBuilder* builder);
private:
Device* device;
};
class RenderPass : public RenderPassBase {
public:
RenderPass(Device* device, RenderPassBuilder* builder);

View File

@ -13,7 +13,9 @@
// limitations under the License.
#include "D3D12Backend.h"
#include "BufferD3D12.h"
#include "CommandBufferD3D12.h"
#include "InputStateD3D12.h"
#include "PipelineD3D12.h"
#include "PipelineLayoutD3D12.h"
#include "QueueD3D12.h"

View File

@ -0,0 +1,82 @@
// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "InputStateD3D12.h"
namespace backend {
namespace d3d12 {
static DXGI_FORMAT VertexFormatType(nxt::VertexFormat format) {
switch (format) {
case nxt::VertexFormat::FloatR32G32B32A32:
return DXGI_FORMAT_R32G32B32A32_FLOAT;
case nxt::VertexFormat::FloatR32G32B32:
return DXGI_FORMAT_R32G32B32_FLOAT;
case nxt::VertexFormat::FloatR32G32:
return DXGI_FORMAT_R32G32_FLOAT;
}
}
static D3D12_INPUT_CLASSIFICATION InputStepModeFunction(nxt::InputStepMode mode) {
switch (mode) {
case nxt::InputStepMode::Vertex:
return D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
case nxt::InputStepMode::Instance:
return D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA;
}
}
InputState::InputState(Device* device, InputStateBuilder* builder)
: InputStateBase(builder), device(device) {
const auto& attributesSetMask = GetAttributesSetMask();
size_t count = 0;
for (size_t i = 0; i < attributesSetMask.size(); ++i) {
if (!attributesSetMask[i]) {
continue;
}
D3D12_INPUT_ELEMENT_DESC& inputElementDescriptor = inputElementDescriptors[count++];
const AttributeInfo& attribute = GetAttribute(i);
// If the HLSL semantic is TEXCOORDN the SemanticName should be "TEXCOORD" and the SemanticIndex N
inputElementDescriptor.SemanticName = "TEXCOORD";
inputElementDescriptor.SemanticIndex = i;
inputElementDescriptor.Format = VertexFormatType(attribute.format);
inputElementDescriptor.InputSlot = attribute.bindingSlot;
const InputInfo& input = GetInput(attribute.bindingSlot);
inputElementDescriptor.AlignedByteOffset = attribute.offset;
inputElementDescriptor.InputSlotClass = InputStepModeFunction(input.stepMode);
if (inputElementDescriptor.InputSlotClass == D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA) {
inputElementDescriptor.InstanceDataStepRate = 0;
} else {
inputElementDescriptor.InstanceDataStepRate = 1;
}
}
inputLayoutDescriptor.pInputElementDescs = inputElementDescriptors;
inputLayoutDescriptor.NumElements = count;
}
const D3D12_INPUT_LAYOUT_DESC& InputState::GetD3D12InputLayoutDescriptor() const {
return inputLayoutDescriptor;
}
}
}

View File

@ -0,0 +1,42 @@
// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BACKEND_D3D12_INPUTSTATED3D12_H_
#define BACKEND_D3D12_INPUTSTATED3D12_H_
#include "common/InputState.h"
#include "d3d12_platform.h"
namespace backend {
namespace d3d12 {
class Device;
class InputState : public InputStateBase {
public:
InputState(Device* device, InputStateBuilder* builder);
const D3D12_INPUT_LAYOUT_DESC& GetD3D12InputLayoutDescriptor() const;
private:
Device* device;
D3D12_INPUT_LAYOUT_DESC inputLayoutDescriptor;
D3D12_INPUT_ELEMENT_DESC inputElementDescriptors[kMaxVertexAttributes];
};
}
}
#endif // BACKEND_D3D12_INPUTSTATED3D12_H_

View File

@ -15,6 +15,7 @@
#include "PipelineD3D12.h"
#include "D3D12Backend.h"
#include "InputStateD3D12.h"
#include "ShaderModuleD3D12.h"
#include "PipelineLayoutD3D12.h"
@ -115,6 +116,9 @@ namespace d3d12 {
}
}
InputState* inputState = ToBackend(GetInputState());
descriptor.InputLayout = inputState->GetD3D12InputLayoutDescriptor();
descriptor.pRootSignature = ToBackend(GetLayout())->GetRootSignature().Get();
descriptor.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;

View File

@ -31,7 +31,6 @@ namespace d3d12 {
nullptr,
IID_PPV_ARGS(&commandList)
));
ASSERT_SUCCESS(commandList->Close());
ASSERT_SUCCESS(device->GetD3D12Device()->CreateFence(fenceValue, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)));
fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
@ -39,10 +38,22 @@ namespace d3d12 {
}
void Queue::Submit(uint32_t numCommands, CommandBuffer* const * commands) {
// TODO(enga@google.com): This will stall on the previous submit because
ComPtr<ID3D12CommandAllocator> pendingCommandAllocator = device->GetPendingCommandAllocator();
ComPtr<ID3D12GraphicsCommandList> pendingCommandList = device->GetPendingCommandList();
ASSERT_SUCCESS(pendingCommandList->Close());
for (uint32_t i = 0; i < numCommands; ++i) {
commands[i]->FillCommands(commandList);
}
ASSERT_SUCCESS(commandList->Close());
ID3D12CommandList* commandLists[] = { pendingCommandList.Get(), commandList.Get() };
device->GetCommandQueue()->ExecuteCommandLists(_countof(commandLists), commandLists);
// TODO(enga@google.com): This will stall on the submit because
// the commands must finish exeuting before the ID3D12CommandAllocator is reset.
// This should be fixed / optimized by using multiple command allocators.
const uint64_t currentFence = fenceValue++;
const uint64_t currentFence = ++fenceValue;
ASSERT_SUCCESS(device->GetCommandQueue()->Signal(fence.Get(), fenceValue));
if (fence->GetCompletedValue() < currentFence) {
@ -51,16 +62,9 @@ namespace d3d12 {
}
ASSERT_SUCCESS(commandAllocator->Reset());
ASSERT_SUCCESS(pendingCommandAllocator->Reset());
ASSERT_SUCCESS(pendingCommandList->Reset(pendingCommandAllocator.Get(), NULL));
ASSERT_SUCCESS(commandList->Reset(commandAllocator.Get(), NULL));
for (uint32_t i = 0; i < numCommands; ++i) {
commands[i]->FillCommands(commandList);
}
ASSERT_SUCCESS(commandList->Close());
ID3D12CommandList* commandLists[] = { commandList.Get() };
device->GetCommandQueue()->ExecuteCommandLists(_countof(commandLists), commandLists);
}
}