D3D12 vertex and index buffers with resource transitions
This commit is contained in:
parent
459537491b
commit
d251356783
|
@ -216,10 +216,14 @@ if (WIN32)
|
||||||
SetPIC(d3d12_autogen)
|
SetPIC(d3d12_autogen)
|
||||||
|
|
||||||
list(APPEND BACKEND_SOURCES
|
list(APPEND BACKEND_SOURCES
|
||||||
|
${D3D12_DIR}/BufferD3D12.cpp
|
||||||
|
${D3D12_DIR}/BufferD3D12.h
|
||||||
${D3D12_DIR}/CommandBufferD3D12.cpp
|
${D3D12_DIR}/CommandBufferD3D12.cpp
|
||||||
${D3D12_DIR}/CommandBufferD3D12.h
|
${D3D12_DIR}/CommandBufferD3D12.h
|
||||||
${D3D12_DIR}/D3D12Backend.cpp
|
${D3D12_DIR}/D3D12Backend.cpp
|
||||||
${D3D12_DIR}/D3D12Backend.h
|
${D3D12_DIR}/D3D12Backend.h
|
||||||
|
${D3D12_DIR}/InputStateD3D12.cpp
|
||||||
|
${D3D12_DIR}/InputStateD3D12.h
|
||||||
${D3D12_DIR}/PipelineD3D12.cpp
|
${D3D12_DIR}/PipelineD3D12.cpp
|
||||||
${D3D12_DIR}/PipelineD3D12.h
|
${D3D12_DIR}/PipelineD3D12.h
|
||||||
${D3D12_DIR}/PipelineLayoutD3D12.cpp
|
${D3D12_DIR}/PipelineLayoutD3D12.cpp
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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_
|
|
@ -16,156 +16,212 @@
|
||||||
|
|
||||||
#include "common/Commands.h"
|
#include "common/Commands.h"
|
||||||
#include "D3D12Backend.h"
|
#include "D3D12Backend.h"
|
||||||
|
#include "BufferD3D12.h"
|
||||||
|
#include "InputStateD3D12.h"
|
||||||
#include "PipelineD3D12.h"
|
#include "PipelineD3D12.h"
|
||||||
#include "PipelineLayoutD3D12.h"
|
#include "PipelineLayoutD3D12.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
namespace d3d12 {
|
namespace d3d12 {
|
||||||
|
|
||||||
CommandBuffer::CommandBuffer(Device* device, CommandBufferBuilder* builder)
|
namespace {
|
||||||
: CommandBufferBase(builder), device(device), commands(builder->AcquireCommands()) {
|
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() {
|
CommandBuffer::CommandBuffer(Device* device, CommandBufferBuilder* builder)
|
||||||
FreeCommands(&commands);
|
: CommandBufferBase(builder), device(device), commands(builder->AcquireCommands()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBuffer::FillCommands(ComPtr<ID3D12GraphicsCommandList> commandList) {
|
CommandBuffer::~CommandBuffer() {
|
||||||
Command type;
|
FreeCommands(&commands);
|
||||||
Pipeline* lastPipeline = nullptr;
|
}
|
||||||
|
|
||||||
RenderPass* currentRenderPass = nullptr;
|
void CommandBuffer::FillCommands(ComPtr<ID3D12GraphicsCommandList> commandList) {
|
||||||
Framebuffer* currentFramebuffer = nullptr;
|
Command type;
|
||||||
|
Pipeline* lastPipeline = nullptr;
|
||||||
|
|
||||||
while(commands.NextCommandId(&type)) {
|
RenderPass* currentRenderPass = nullptr;
|
||||||
switch (type) {
|
Framebuffer* currentFramebuffer = nullptr;
|
||||||
case Command::AdvanceSubpass:
|
|
||||||
{
|
|
||||||
commands.NextCommand<AdvanceSubpassCmd>();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::BeginRenderPass:
|
while(commands.NextCommandId(&type)) {
|
||||||
{
|
switch (type) {
|
||||||
BeginRenderPassCmd* beginRenderPassCmd = commands.NextCommand<BeginRenderPassCmd>();
|
case Command::AdvanceSubpass:
|
||||||
currentRenderPass = ToBackend(beginRenderPassCmd->renderPass.Get());
|
{
|
||||||
currentFramebuffer = ToBackend(beginRenderPassCmd->framebuffer.Get());
|
commands.NextCommand<AdvanceSubpassCmd>();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
float width = (float) currentFramebuffer->GetWidth();
|
case Command::BeginRenderPass:
|
||||||
float height = (float) currentFramebuffer->GetHeight();
|
{
|
||||||
D3D12_VIEWPORT viewport = { 0.f, 0.f, width, height, 0.f, 1.f };
|
BeginRenderPassCmd* beginRenderPassCmd = commands.NextCommand<BeginRenderPassCmd>();
|
||||||
D3D12_RECT scissorRect = { 0.f, 0.f, width, height };
|
currentRenderPass = ToBackend(beginRenderPassCmd->renderPass.Get());
|
||||||
commandList->RSSetViewports(1, &viewport);
|
currentFramebuffer = ToBackend(beginRenderPassCmd->framebuffer.Get());
|
||||||
commandList->RSSetScissorRects(1, &scissorRect);
|
|
||||||
commandList->OMSetRenderTargets(1, &device->GetCurrentRenderTargetDescriptor(), FALSE, nullptr);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::CopyBufferToBuffer:
|
float width = (float) currentFramebuffer->GetWidth();
|
||||||
{
|
float height = (float) currentFramebuffer->GetHeight();
|
||||||
CopyBufferToBufferCmd* copy = commands.NextCommand<CopyBufferToBufferCmd>();
|
D3D12_VIEWPORT viewport = { 0.f, 0.f, width, height, 0.f, 1.f };
|
||||||
}
|
D3D12_RECT scissorRect = { 0.f, 0.f, width, height };
|
||||||
break;
|
commandList->RSSetViewports(1, &viewport);
|
||||||
|
commandList->RSSetScissorRects(1, &scissorRect);
|
||||||
|
commandList->OMSetRenderTargets(1, &device->GetCurrentRenderTargetDescriptor(), FALSE, nullptr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Command::CopyBufferToBuffer:
|
||||||
|
{
|
||||||
|
CopyBufferToBufferCmd* copy = commands.NextCommand<CopyBufferToBufferCmd>();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case Command::CopyBufferToTexture:
|
case Command::CopyBufferToTexture:
|
||||||
{
|
{
|
||||||
CopyBufferToTextureCmd* copy = commands.NextCommand<CopyBufferToTextureCmd>();
|
CopyBufferToTextureCmd* copy = commands.NextCommand<CopyBufferToTextureCmd>();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::Dispatch:
|
case Command::Dispatch:
|
||||||
{
|
{
|
||||||
DispatchCmd* dispatch = commands.NextCommand<DispatchCmd>();
|
DispatchCmd* dispatch = commands.NextCommand<DispatchCmd>();
|
||||||
|
|
||||||
ASSERT(lastPipeline->IsCompute());
|
ASSERT(lastPipeline->IsCompute());
|
||||||
commandList->Dispatch(dispatch->x, dispatch->y, dispatch->z);
|
commandList->Dispatch(dispatch->x, dispatch->y, dispatch->z);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::DrawArrays:
|
case Command::DrawArrays:
|
||||||
{
|
{
|
||||||
DrawArraysCmd* draw = commands.NextCommand<DrawArraysCmd>();
|
DrawArraysCmd* draw = commands.NextCommand<DrawArraysCmd>();
|
||||||
|
|
||||||
commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
commandList->DrawInstanced(
|
commandList->DrawInstanced(
|
||||||
draw->vertexCount,
|
draw->vertexCount,
|
||||||
draw->instanceCount,
|
draw->instanceCount,
|
||||||
draw->firstVertex,
|
draw->firstVertex,
|
||||||
draw->firstInstance
|
draw->firstInstance
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::DrawElements:
|
case Command::DrawElements:
|
||||||
{
|
{
|
||||||
DrawElementsCmd* draw = commands.NextCommand<DrawElementsCmd>();
|
DrawElementsCmd* draw = commands.NextCommand<DrawElementsCmd>();
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::EndRenderPass:
|
commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
{
|
commandList->DrawIndexedInstanced(
|
||||||
EndRenderPassCmd* cmd = commands.NextCommand<EndRenderPassCmd>();
|
draw->indexCount,
|
||||||
}
|
draw->instanceCount,
|
||||||
break;
|
draw->firstIndex,
|
||||||
|
0,
|
||||||
|
draw->firstInstance
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case Command::SetPipeline:
|
case Command::EndRenderPass:
|
||||||
{
|
{
|
||||||
SetPipelineCmd* cmd = commands.NextCommand<SetPipelineCmd>();
|
EndRenderPassCmd* cmd = commands.NextCommand<EndRenderPassCmd>();
|
||||||
lastPipeline = ToBackend(cmd->pipeline).Get();
|
}
|
||||||
PipelineLayout* pipelineLayout = ToBackend(lastPipeline->GetLayout());
|
break;
|
||||||
|
|
||||||
// TODO
|
case Command::SetPipeline:
|
||||||
if (lastPipeline->IsCompute()) {
|
{
|
||||||
} else {
|
SetPipelineCmd* cmd = commands.NextCommand<SetPipelineCmd>();
|
||||||
commandList->SetGraphicsRootSignature(pipelineLayout->GetRootSignature().Get());
|
lastPipeline = ToBackend(cmd->pipeline).Get();
|
||||||
commandList->SetPipelineState(lastPipeline->GetRenderPipelineState().Get());
|
PipelineLayout* pipelineLayout = ToBackend(lastPipeline->GetLayout());
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::SetPushConstants:
|
// TODO
|
||||||
{
|
if (lastPipeline->IsCompute()) {
|
||||||
SetPushConstantsCmd* cmd = commands.NextCommand<SetPushConstantsCmd>();
|
} else {
|
||||||
}
|
commandList->SetGraphicsRootSignature(pipelineLayout->GetRootSignature().Get());
|
||||||
break;
|
commandList->SetPipelineState(lastPipeline->GetRenderPipelineState().Get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case Command::SetStencilReference:
|
case Command::SetPushConstants:
|
||||||
|
{
|
||||||
|
SetPushConstantsCmd* cmd = commands.NextCommand<SetPushConstantsCmd>();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Command::SetStencilReference:
|
||||||
{
|
{
|
||||||
SetStencilReferenceCmd* cmd = commands.NextCommand<SetStencilReferenceCmd>();
|
SetStencilReferenceCmd* cmd = commands.NextCommand<SetStencilReferenceCmd>();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::SetBindGroup:
|
case Command::SetBindGroup:
|
||||||
{
|
{
|
||||||
SetBindGroupCmd* cmd = commands.NextCommand<SetBindGroupCmd>();
|
SetBindGroupCmd* cmd = commands.NextCommand<SetBindGroupCmd>();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::SetIndexBuffer:
|
case Command::SetIndexBuffer:
|
||||||
{
|
{
|
||||||
SetIndexBufferCmd* cmd = commands.NextCommand<SetIndexBufferCmd>();
|
SetIndexBufferCmd* cmd = commands.NextCommand<SetIndexBufferCmd>();
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::SetVertexBuffers:
|
Buffer* buffer = ToBackend(cmd->buffer.Get());
|
||||||
{
|
D3D12_INDEX_BUFFER_VIEW bufferView;
|
||||||
SetVertexBuffersCmd* cmd = commands.NextCommand<SetVertexBuffersCmd>();
|
bufferView.BufferLocation = buffer->GetVA() + cmd->offset;
|
||||||
}
|
bufferView.SizeInBytes = buffer->GetSize() - cmd->offset;
|
||||||
break;
|
bufferView.Format = DXGIIndexFormat(cmd->format);
|
||||||
|
|
||||||
case Command::TransitionBufferUsage:
|
commandList->IASetIndexBuffer(&bufferView);
|
||||||
{
|
}
|
||||||
TransitionBufferUsageCmd* cmd = commands.NextCommand<TransitionBufferUsageCmd>();
|
break;
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::TransitionTextureUsage:
|
case Command::SetVertexBuffers:
|
||||||
{
|
{
|
||||||
TransitionTextureUsageCmd* cmd = commands.NextCommand<TransitionTextureUsageCmd>();
|
SetVertexBuffersCmd* cmd = commands.NextCommand<SetVertexBuffersCmd>();
|
||||||
}
|
auto buffers = commands.NextData<Ref<BufferBase>>(cmd->count);
|
||||||
break;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,9 @@
|
||||||
|
|
||||||
#include "D3D12Backend.h"
|
#include "D3D12Backend.h"
|
||||||
|
|
||||||
|
#include "BufferD3D12.h"
|
||||||
#include "CommandBufferD3D12.h"
|
#include "CommandBufferD3D12.h"
|
||||||
|
#include "InputStateD3D12.h"
|
||||||
#include "PipelineD3D12.h"
|
#include "PipelineD3D12.h"
|
||||||
#include "PipelineLayoutD3D12.h"
|
#include "PipelineLayoutD3D12.h"
|
||||||
#include "QueueD3D12.h"
|
#include "QueueD3D12.h"
|
||||||
|
@ -51,6 +53,15 @@ namespace d3d12 {
|
||||||
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||||
ASSERT_SUCCESS(d3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&commandQueue)));
|
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() {
|
Device::~Device() {
|
||||||
|
@ -64,6 +75,14 @@ namespace d3d12 {
|
||||||
return commandQueue;
|
return commandQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ComPtr<ID3D12CommandAllocator> Device::GetPendingCommandAllocator() {
|
||||||
|
return pendingCommandAllocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComPtr<ID3D12GraphicsCommandList> Device::GetPendingCommandList() {
|
||||||
|
return pendingCommandList;
|
||||||
|
}
|
||||||
|
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE Device::GetCurrentRenderTargetDescriptor() {
|
D3D12_CPU_DESCRIPTOR_HANDLE Device::GetCurrentRenderTargetDescriptor() {
|
||||||
return renderTargetDescriptor;
|
return renderTargetDescriptor;
|
||||||
}
|
}
|
||||||
|
@ -139,26 +158,6 @@ namespace d3d12 {
|
||||||
: BindGroupLayoutBase(builder), device(device) {
|
: 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::BufferView(Device* device, BufferViewBuilder* builder)
|
BufferView::BufferView(Device* device, BufferViewBuilder* builder)
|
||||||
|
@ -177,12 +176,6 @@ namespace d3d12 {
|
||||||
: FramebufferBase(builder), device(device) {
|
: FramebufferBase(builder), device(device) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// InputState
|
|
||||||
|
|
||||||
InputState::InputState(Device* device, InputStateBuilder * builder)
|
|
||||||
: InputStateBase(builder), device(device) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// RenderPass
|
// RenderPass
|
||||||
|
|
||||||
RenderPass::RenderPass(Device* device, RenderPassBuilder* builder)
|
RenderPass::RenderPass(Device* device, RenderPassBuilder* builder)
|
||||||
|
|
|
@ -106,6 +106,8 @@ namespace d3d12 {
|
||||||
|
|
||||||
ComPtr<ID3D12Device> GetD3D12Device();
|
ComPtr<ID3D12Device> GetD3D12Device();
|
||||||
ComPtr<ID3D12CommandQueue> GetCommandQueue();
|
ComPtr<ID3D12CommandQueue> GetCommandQueue();
|
||||||
|
ComPtr<ID3D12CommandAllocator> GetPendingCommandAllocator();
|
||||||
|
ComPtr<ID3D12GraphicsCommandList> GetPendingCommandList();
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE GetCurrentRenderTargetDescriptor();
|
D3D12_CPU_DESCRIPTOR_HANDLE GetCurrentRenderTargetDescriptor();
|
||||||
|
|
||||||
void SetNextRenderTargetDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE renderTargetDescriptor);
|
void SetNextRenderTargetDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE renderTargetDescriptor);
|
||||||
|
@ -117,6 +119,8 @@ namespace d3d12 {
|
||||||
private:
|
private:
|
||||||
ComPtr<ID3D12Device> d3d12Device;
|
ComPtr<ID3D12Device> d3d12Device;
|
||||||
ComPtr<ID3D12CommandQueue> commandQueue;
|
ComPtr<ID3D12CommandQueue> commandQueue;
|
||||||
|
ComPtr<ID3D12CommandAllocator> pendingCommandAllocator;
|
||||||
|
ComPtr<ID3D12GraphicsCommandList> pendingCommandList;
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE renderTargetDescriptor;
|
D3D12_CPU_DESCRIPTOR_HANDLE renderTargetDescriptor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -137,19 +141,6 @@ namespace d3d12 {
|
||||||
Device* device;
|
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 {
|
class BufferView : public BufferViewBase {
|
||||||
public:
|
public:
|
||||||
BufferView(Device* device, BufferViewBuilder* builder);
|
BufferView(Device* device, BufferViewBuilder* builder);
|
||||||
|
@ -174,14 +165,6 @@ namespace d3d12 {
|
||||||
Device* device;
|
Device* device;
|
||||||
};
|
};
|
||||||
|
|
||||||
class InputState : public InputStateBase {
|
|
||||||
public:
|
|
||||||
InputState(Device* device, InputStateBuilder* builder);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Device* device;
|
|
||||||
};
|
|
||||||
|
|
||||||
class RenderPass : public RenderPassBase {
|
class RenderPass : public RenderPassBase {
|
||||||
public:
|
public:
|
||||||
RenderPass(Device* device, RenderPassBuilder* builder);
|
RenderPass(Device* device, RenderPassBuilder* builder);
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "D3D12Backend.h"
|
#include "D3D12Backend.h"
|
||||||
|
#include "BufferD3D12.h"
|
||||||
#include "CommandBufferD3D12.h"
|
#include "CommandBufferD3D12.h"
|
||||||
|
#include "InputStateD3D12.h"
|
||||||
#include "PipelineD3D12.h"
|
#include "PipelineD3D12.h"
|
||||||
#include "PipelineLayoutD3D12.h"
|
#include "PipelineLayoutD3D12.h"
|
||||||
#include "QueueD3D12.h"
|
#include "QueueD3D12.h"
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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_
|
|
@ -15,6 +15,7 @@
|
||||||
#include "PipelineD3D12.h"
|
#include "PipelineD3D12.h"
|
||||||
|
|
||||||
#include "D3D12Backend.h"
|
#include "D3D12Backend.h"
|
||||||
|
#include "InputStateD3D12.h"
|
||||||
#include "ShaderModuleD3D12.h"
|
#include "ShaderModuleD3D12.h"
|
||||||
#include "PipelineLayoutD3D12.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.pRootSignature = ToBackend(GetLayout())->GetRootSignature().Get();
|
||||||
|
|
||||||
descriptor.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
|
descriptor.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
|
||||||
|
|
|
@ -31,7 +31,6 @@ namespace d3d12 {
|
||||||
nullptr,
|
nullptr,
|
||||||
IID_PPV_ARGS(&commandList)
|
IID_PPV_ARGS(&commandList)
|
||||||
));
|
));
|
||||||
ASSERT_SUCCESS(commandList->Close());
|
|
||||||
|
|
||||||
ASSERT_SUCCESS(device->GetD3D12Device()->CreateFence(fenceValue, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)));
|
ASSERT_SUCCESS(device->GetD3D12Device()->CreateFence(fenceValue, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)));
|
||||||
fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||||
|
@ -39,10 +38,22 @@ namespace d3d12 {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Queue::Submit(uint32_t numCommands, CommandBuffer* const * commands) {
|
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.
|
// the commands must finish exeuting before the ID3D12CommandAllocator is reset.
|
||||||
// This should be fixed / optimized by using multiple command allocators.
|
// 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));
|
ASSERT_SUCCESS(device->GetCommandQueue()->Signal(fence.Get(), fenceValue));
|
||||||
|
|
||||||
if (fence->GetCompletedValue() < currentFence) {
|
if (fence->GetCompletedValue() < currentFence) {
|
||||||
|
@ -51,16 +62,9 @@ namespace d3d12 {
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_SUCCESS(commandAllocator->Reset());
|
ASSERT_SUCCESS(commandAllocator->Reset());
|
||||||
|
ASSERT_SUCCESS(pendingCommandAllocator->Reset());
|
||||||
|
ASSERT_SUCCESS(pendingCommandList->Reset(pendingCommandAllocator.Get(), NULL));
|
||||||
ASSERT_SUCCESS(commandList->Reset(commandAllocator.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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue