Split Pipeline in Render and Compute, D3D12 part

This commit is contained in:
Corentin Wallez 2017-07-15 01:28:31 -04:00 committed by Corentin Wallez
parent 66ff447216
commit 136cae5ee2
10 changed files with 368 additions and 274 deletions

View File

@ -215,6 +215,8 @@ if (NXT_ENABLE_D3D12)
${D3D12_DIR}/CommandAllocatorManager.h ${D3D12_DIR}/CommandAllocatorManager.h
${D3D12_DIR}/CommandBufferD3D12.cpp ${D3D12_DIR}/CommandBufferD3D12.cpp
${D3D12_DIR}/CommandBufferD3D12.h ${D3D12_DIR}/CommandBufferD3D12.h
${D3D12_DIR}/ComputePipelineD3D12.cpp
${D3D12_DIR}/ComputePipelineD3D12.h
${D3D12_DIR}/DescriptorHeapAllocator.cpp ${D3D12_DIR}/DescriptorHeapAllocator.cpp
${D3D12_DIR}/DescriptorHeapAllocator.h ${D3D12_DIR}/DescriptorHeapAllocator.h
${D3D12_DIR}/D3D12Backend.cpp ${D3D12_DIR}/D3D12Backend.cpp
@ -223,12 +225,12 @@ if (NXT_ENABLE_D3D12)
${D3D12_DIR}/FramebufferD3D12.h ${D3D12_DIR}/FramebufferD3D12.h
${D3D12_DIR}/InputStateD3D12.cpp ${D3D12_DIR}/InputStateD3D12.cpp
${D3D12_DIR}/InputStateD3D12.h ${D3D12_DIR}/InputStateD3D12.h
${D3D12_DIR}/PipelineD3D12.cpp
${D3D12_DIR}/PipelineD3D12.h
${D3D12_DIR}/PipelineLayoutD3D12.cpp ${D3D12_DIR}/PipelineLayoutD3D12.cpp
${D3D12_DIR}/PipelineLayoutD3D12.h ${D3D12_DIR}/PipelineLayoutD3D12.h
${D3D12_DIR}/QueueD3D12.cpp ${D3D12_DIR}/QueueD3D12.cpp
${D3D12_DIR}/QueueD3D12.h ${D3D12_DIR}/QueueD3D12.h
${D3D12_DIR}/RenderPipelineD3D12.cpp
${D3D12_DIR}/RenderPipelineD3D12.h
${D3D12_DIR}/ResourceAllocator.cpp ${D3D12_DIR}/ResourceAllocator.cpp
${D3D12_DIR}/ResourceAllocator.h ${D3D12_DIR}/ResourceAllocator.h
${D3D12_DIR}/ResourceUploader.cpp ${D3D12_DIR}/ResourceUploader.cpp

View File

@ -19,11 +19,12 @@
#include "backend/d3d12/BindGroupD3D12.h" #include "backend/d3d12/BindGroupD3D12.h"
#include "backend/d3d12/BindGroupLayoutD3D12.h" #include "backend/d3d12/BindGroupLayoutD3D12.h"
#include "backend/d3d12/BufferD3D12.h" #include "backend/d3d12/BufferD3D12.h"
#include "backend/d3d12/ComputePipelineD3D12.h"
#include "backend/d3d12/DescriptorHeapAllocator.h" #include "backend/d3d12/DescriptorHeapAllocator.h"
#include "backend/d3d12/FramebufferD3D12.h" #include "backend/d3d12/FramebufferD3D12.h"
#include "backend/d3d12/InputStateD3D12.h" #include "backend/d3d12/InputStateD3D12.h"
#include "backend/d3d12/PipelineD3D12.h"
#include "backend/d3d12/PipelineLayoutD3D12.h" #include "backend/d3d12/PipelineLayoutD3D12.h"
#include "backend/d3d12/RenderPipelineD3D12.h"
#include "backend/d3d12/ResourceAllocator.h" #include "backend/d3d12/ResourceAllocator.h"
#include "backend/d3d12/SamplerD3D12.h" #include "backend/d3d12/SamplerD3D12.h"
#include "backend/d3d12/TextureD3D12.h" #include "backend/d3d12/TextureD3D12.h"
@ -52,12 +53,17 @@ namespace d3d12 {
DescriptorHeapHandle cbvSrvUavGPUDescriptorHeap = {}; DescriptorHeapHandle cbvSrvUavGPUDescriptorHeap = {};
DescriptorHeapHandle samplerGPUDescriptorHeap = {}; DescriptorHeapHandle samplerGPUDescriptorHeap = {};
std::array<BindGroup*, kMaxBindGroups> bindGroups = {}; std::array<BindGroup*, kMaxBindGroups> bindGroups = {};
bool inCompute = false;
Device* device; Device* device;
BindGroupStateTracker(Device* device) : device(device) { BindGroupStateTracker(Device* device) : device(device) {
} }
void SetInComputePass(bool inCompute) {
this->inCompute = inCompute;
}
void TrackSetBindGroup(BindGroup* group, uint32_t index) { void TrackSetBindGroup(BindGroup* group, uint32_t index) {
if (bindGroups[index] != group) { if (bindGroups[index] != group) {
bindGroups[index] = group; bindGroups[index] = group;
@ -70,25 +76,38 @@ namespace d3d12 {
} }
} }
void TrackSetBindInheritedGroup(uint32_t index) { void TrackInheritedGroups(PipelineLayout* oldLayout, PipelineLayout* newLayout) {
BindGroup* group = bindGroups[index]; if (oldLayout == nullptr) {
if (group != nullptr) { return;
TrackSetBindGroup(group, index); }
auto mask = newLayout->GetBindGroupsLayoutMask();
for (uint32_t i = 0; i < kMaxBindGroups; ++i) {
// matching bind groups are inherited until they differ
if (mask[i] && oldLayout->GetBindGroupLayout(i) == newLayout->GetBindGroupLayout(i)) {
BindGroup* group = bindGroups[i];
if (group != nullptr) {
TrackSetBindGroup(group, i);
}
}
else {
break;
}
} }
} }
void SetBindGroup(ComPtr<ID3D12GraphicsCommandList> commandList, Pipeline* pipeline, BindGroup* group, uint32_t index, bool force = false) { void SetBindGroup(ComPtr<ID3D12GraphicsCommandList> commandList, PipelineLayout* pipelineLayout, BindGroup* group,
uint32_t index, bool force = false) {
if (bindGroups[index] != group || force) { if (bindGroups[index] != group || force) {
bindGroups[index] = group; bindGroups[index] = group;
PipelineLayout* pipelineLayout = ToBackend(pipeline->GetLayout());
uint32_t cbvUavSrvCount = ToBackend(group->GetLayout())->GetCbvUavSrvDescriptorCount(); uint32_t cbvUavSrvCount = ToBackend(group->GetLayout())->GetCbvUavSrvDescriptorCount();
uint32_t samplerCount = ToBackend(group->GetLayout())->GetSamplerDescriptorCount(); uint32_t samplerCount = ToBackend(group->GetLayout())->GetSamplerDescriptorCount();
if (cbvUavSrvCount > 0) { if (cbvUavSrvCount > 0) {
uint32_t parameterIndex = pipelineLayout->GetCbvUavSrvRootParameterIndex(index); uint32_t parameterIndex = pipelineLayout->GetCbvUavSrvRootParameterIndex(index);
if (pipeline->IsCompute()) { if (inCompute) {
commandList->SetComputeRootDescriptorTable(parameterIndex, cbvSrvUavGPUDescriptorHeap.GetGPUHandle(group->GetCbvUavSrvHeapOffset())); commandList->SetComputeRootDescriptorTable(parameterIndex, cbvSrvUavGPUDescriptorHeap.GetGPUHandle(group->GetCbvUavSrvHeapOffset()));
} else { } else {
commandList->SetGraphicsRootDescriptorTable(parameterIndex, cbvSrvUavGPUDescriptorHeap.GetGPUHandle(group->GetCbvUavSrvHeapOffset())); commandList->SetGraphicsRootDescriptorTable(parameterIndex, cbvSrvUavGPUDescriptorHeap.GetGPUHandle(group->GetCbvUavSrvHeapOffset()));
@ -98,7 +117,7 @@ namespace d3d12 {
if (samplerCount > 0) { if (samplerCount > 0) {
uint32_t parameterIndex = pipelineLayout->GetSamplerRootParameterIndex(index); uint32_t parameterIndex = pipelineLayout->GetSamplerRootParameterIndex(index);
if (pipeline->IsCompute()) { if (inCompute) {
commandList->SetComputeRootDescriptorTable(parameterIndex, samplerGPUDescriptorHeap.GetGPUHandle(group->GetSamplerHeapOffset())); commandList->SetComputeRootDescriptorTable(parameterIndex, samplerGPUDescriptorHeap.GetGPUHandle(group->GetSamplerHeapOffset()));
} else { } else {
commandList->SetGraphicsRootDescriptorTable(parameterIndex, samplerGPUDescriptorHeap.GetGPUHandle(group->GetSamplerHeapOffset())); commandList->SetGraphicsRootDescriptorTable(parameterIndex, samplerGPUDescriptorHeap.GetGPUHandle(group->GetSamplerHeapOffset()));
@ -107,10 +126,22 @@ namespace d3d12 {
} }
} }
void SetInheritedBindGroup(ComPtr<ID3D12GraphicsCommandList> commandList, Pipeline* pipeline, uint32_t index) { void SetInheritedBindGroups(ComPtr<ID3D12GraphicsCommandList> commandList, PipelineLayout* oldLayout, PipelineLayout* newLayout) {
BindGroup* group = bindGroups[index]; if (oldLayout == nullptr) {
if (group != nullptr) { return;
SetBindGroup(commandList, pipeline, group, index, true); }
auto mask = newLayout->GetBindGroupsLayoutMask();
for (uint32_t i = 0; i < kMaxBindGroups; ++i) {
// matching bind groups are inherited until they differ
if (mask[i] && oldLayout->GetBindGroupLayout(i) == oldLayout->GetBindGroupLayout(i)) {
BindGroup* group = bindGroups[i];
if (group != nullptr) {
SetBindGroup(commandList, newLayout, group, i, true);
}
}
else {
break;
}
} }
} }
@ -131,30 +162,24 @@ namespace d3d12 {
{ {
Command type; Command type;
Pipeline* lastPipeline = nullptr;
PipelineLayout* lastLayout = nullptr; PipelineLayout* lastLayout = nullptr;
while (commands->NextCommandId(&type)) { while (commands->NextCommandId(&type)) {
switch (type) { switch (type) {
case Command::SetPipeline: case Command::SetComputePipeline:
{ {
SetPipelineCmd* cmd = commands->NextCommand<SetPipelineCmd>(); SetComputePipelineCmd* cmd = commands->NextCommand<SetComputePipelineCmd>();
Pipeline* pipeline = ToBackend(cmd->pipeline).Get(); PipelineLayout* layout = ToBackend(cmd->pipeline->GetLayout());
PipelineLayout* layout = ToBackend(pipeline->GetLayout()); bindingTracker->TrackInheritedGroups(lastLayout, layout);
lastLayout = layout;
}
break;
if (lastLayout) { case Command::SetRenderPipeline:
auto mask = layout->GetBindGroupsLayoutMask(); {
for (uint32_t i = 0; i < kMaxBindGroups; ++i) { SetRenderPipelineCmd* cmd = commands->NextCommand<SetRenderPipelineCmd>();
// matching bind groups are inherited until they differ PipelineLayout* layout = ToBackend(cmd->pipeline->GetLayout());
if (mask[i] && lastLayout->GetBindGroupLayout(i) == layout->GetBindGroupLayout(i)) { bindingTracker->TrackInheritedGroups(lastLayout, layout);
bindingTracker->TrackSetBindInheritedGroup(i);
} else {
break;
}
}
}
lastPipeline = pipeline;
lastLayout = layout; lastLayout = layout;
} }
break; break;
@ -243,7 +268,7 @@ namespace d3d12 {
} }
Command type; Command type;
Pipeline* lastPipeline = nullptr; RenderPipeline* lastRenderPipeline = nullptr;
PipelineLayout* lastLayout = nullptr; PipelineLayout* lastLayout = nullptr;
RenderPass* currentRenderPass = nullptr; RenderPass* currentRenderPass = nullptr;
@ -255,6 +280,7 @@ namespace d3d12 {
case Command::BeginComputePass: case Command::BeginComputePass:
{ {
commands.NextCommand<BeginComputePassCmd>(); commands.NextCommand<BeginComputePassCmd>();
bindingTracker.SetInComputePass(true);
} }
break; break;
@ -351,8 +377,6 @@ namespace d3d12 {
case Command::Dispatch: case Command::Dispatch:
{ {
DispatchCmd* dispatch = commands.NextCommand<DispatchCmd>(); DispatchCmd* dispatch = commands.NextCommand<DispatchCmd>();
ASSERT(lastPipeline->IsCompute());
commandList->Dispatch(dispatch->x, dispatch->y, dispatch->z); commandList->Dispatch(dispatch->x, dispatch->y, dispatch->z);
} }
break; break;
@ -389,6 +413,7 @@ namespace d3d12 {
case Command::EndComputePass: case Command::EndComputePass:
{ {
commands.NextCommand<EndComputePassCmd>(); commands.NextCommand<EndComputePassCmd>();
bindingTracker.SetInComputePass(false);
} }
break; break;
@ -405,35 +430,30 @@ namespace d3d12 {
} }
break; break;
case Command::SetPipeline: case Command::SetComputePipeline:
{ {
SetPipelineCmd* cmd = commands.NextCommand<SetPipelineCmd>(); SetComputePipelineCmd* cmd = commands.NextCommand<SetComputePipelineCmd>();
ComputePipeline* pipeline = ToBackend(cmd->pipeline).Get();
Pipeline* pipeline = ToBackend(cmd->pipeline).Get();
PipelineLayout* layout = ToBackend(pipeline->GetLayout()); PipelineLayout* layout = ToBackend(pipeline->GetLayout());
// TODO // TODO(enga@google.com): Implement compute pipelines
if (pipeline->IsCompute()) { bindingTracker.SetInheritedBindGroups(commandList, lastLayout, layout);
} lastLayout = layout;
else { }
commandList->SetGraphicsRootSignature(layout->GetRootSignature().Get()); break;
commandList->SetPipelineState(pipeline->GetRenderPipelineState().Get());
}
if (lastLayout) { case Command::SetRenderPipeline:
auto mask = layout->GetBindGroupsLayoutMask(); {
for (uint32_t i = 0; i < kMaxBindGroups; ++i) { SetRenderPipelineCmd* cmd = commands.NextCommand<SetRenderPipelineCmd>();
// matching bind groups are inherited until they differ RenderPipeline* pipeline = ToBackend(cmd->pipeline).Get();
if (mask[i] && lastLayout->GetBindGroupLayout(i) == layout->GetBindGroupLayout(i)) { PipelineLayout* layout = ToBackend(pipeline->GetLayout());
bindingTracker.SetInheritedBindGroup(commandList, pipeline, i);
} else {
break;
}
}
}
commandList->SetGraphicsRootSignature(layout->GetRootSignature().Get());
commandList->SetPipelineState(pipeline->GetPipelineState().Get());
lastPipeline = pipeline; bindingTracker.SetInheritedBindGroups(commandList, lastLayout, layout);
lastRenderPipeline = pipeline;
lastLayout = layout; lastLayout = layout;
} }
break; break;
@ -454,7 +474,7 @@ namespace d3d12 {
{ {
SetBindGroupCmd* cmd = commands.NextCommand<SetBindGroupCmd>(); SetBindGroupCmd* cmd = commands.NextCommand<SetBindGroupCmd>();
BindGroup* group = ToBackend(cmd->group.Get()); BindGroup* group = ToBackend(cmd->group.Get());
bindingTracker.SetBindGroup(commandList, lastPipeline, group, cmd->index); bindingTracker.SetBindGroup(commandList, lastLayout, group, cmd->index);
} }
break; break;
@ -478,7 +498,7 @@ namespace d3d12 {
auto buffers = commands.NextData<Ref<BufferBase>>(cmd->count); auto buffers = commands.NextData<Ref<BufferBase>>(cmd->count);
auto offsets = commands.NextData<uint32_t>(cmd->count); auto offsets = commands.NextData<uint32_t>(cmd->count);
auto inputState = ToBackend(lastPipeline->GetInputState()); auto inputState = ToBackend(lastRenderPipeline->GetInputState());
std::array<D3D12_VERTEX_BUFFER_VIEW, kMaxVertexInputs> d3d12BufferViews; std::array<D3D12_VERTEX_BUFFER_VIEW, kMaxVertexInputs> d3d12BufferViews;
for (uint32_t i = 0; i < cmd->count; ++i) { for (uint32_t i = 0; i < cmd->count; ++i) {

View File

@ -0,0 +1,75 @@
// 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 "backend/d3d12/ComputePipelineD3D12.h"
#include "backend/d3d12/D3D12Backend.h"
#include "backend/d3d12/ShaderModuleD3D12.h"
#include "backend/d3d12/PipelineLayoutD3D12.h"
#include "common/Assert.h"
#include <d3dcompiler.h>
namespace backend {
namespace d3d12 {
ComputePipeline::ComputePipeline(ComputePipelineBuilder* builder)
: ComputePipelineBase(builder) {
uint32_t compileFlags = 0;
#if defined(_DEBUG)
// Enable better shader debugging with the graphics debugging tools.
compileFlags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
#endif
// SPRIV-cross does matrix multiplication expecting row major matrices
compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;
const auto& module = ToBackend(builder->GetStageInfo(nxt::ShaderStage::Compute).module);
const auto& entryPoint = builder->GetStageInfo(nxt::ShaderStage::Compute).entryPoint;
const auto& hlslSource = module->GetHLSLSource();
ComPtr<ID3DBlob> compiledShader;
ComPtr<ID3DBlob> errors;
if (FAILED(D3DCompile(
hlslSource.c_str(),
hlslSource.length(),
nullptr,
{ nullptr },
nullptr,
entryPoint.c_str(),
"cs_5_0",
compileFlags,
0,
&compiledShader,
&errors
))) {
printf("%s\n", reinterpret_cast<char*>(errors->GetBufferPointer()));
ASSERT(false);
}
D3D12_COMPUTE_PIPELINE_STATE_DESC descriptor = {};
descriptor.pRootSignature = ToBackend(GetLayout())->GetRootSignature().Get();
descriptor.CS.pShaderBytecode = compiledShader->GetBufferPointer();
descriptor.CS.BytecodeLength = compiledShader->GetBufferSize();
Device* device = ToBackend(builder->GetDevice());
device->GetD3D12Device()->CreateComputePipelineState(&descriptor, IID_PPV_ARGS(&pipelineState));
}
ComPtr<ID3D12PipelineState> ComputePipeline::GetPipelineState() {
return pipelineState;
}
}
}

View File

@ -0,0 +1,38 @@
// 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_COMPUTEPIPELINED3D12_H_
#define BACKEND_D3D12_COMPUTEPIPELINED3D12_H_
#include "backend/ComputePipeline.h"
#include "backend/d3d12/d3d12_platform.h"
namespace backend {
namespace d3d12 {
class ComputePipeline : public ComputePipelineBase {
public:
ComputePipeline(ComputePipelineBuilder* builder);
ComPtr<ID3D12PipelineState> GetPipelineState();
private:
ComPtr<ID3D12PipelineState> pipelineState;
};
}
}
#endif // BACKEND_D3D12_COMPUTEPIPELINED3D12_H_

View File

@ -19,12 +19,13 @@
#include "backend/d3d12/BufferD3D12.h" #include "backend/d3d12/BufferD3D12.h"
#include "backend/d3d12/CommandAllocatorManager.h" #include "backend/d3d12/CommandAllocatorManager.h"
#include "backend/d3d12/CommandBufferD3D12.h" #include "backend/d3d12/CommandBufferD3D12.h"
#include "backend/d3d12/ComputePipelineD3D12.h"
#include "backend/d3d12/DescriptorHeapAllocator.h" #include "backend/d3d12/DescriptorHeapAllocator.h"
#include "backend/d3d12/FramebufferD3D12.h" #include "backend/d3d12/FramebufferD3D12.h"
#include "backend/d3d12/InputStateD3D12.h" #include "backend/d3d12/InputStateD3D12.h"
#include "backend/d3d12/PipelineD3D12.h"
#include "backend/d3d12/PipelineLayoutD3D12.h" #include "backend/d3d12/PipelineLayoutD3D12.h"
#include "backend/d3d12/QueueD3D12.h" #include "backend/d3d12/QueueD3D12.h"
#include "backend/d3d12/RenderPipelineD3D12.h"
#include "backend/d3d12/ResourceAllocator.h" #include "backend/d3d12/ResourceAllocator.h"
#include "backend/d3d12/ResourceUploader.h" #include "backend/d3d12/ResourceUploader.h"
#include "backend/d3d12/SamplerD3D12.h" #include "backend/d3d12/SamplerD3D12.h"
@ -222,17 +223,17 @@ namespace d3d12 {
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) { CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
return new CommandBuffer(this, builder); return new CommandBuffer(this, builder);
} }
ComputePipelineBase* Device::CreateComputePipeline(ComputePipelineBuilder* builder) {
return new ComputePipeline(builder);
}
DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) { DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) {
return new DepthStencilState(this, builder); return new DepthStencilState(this, builder);
} }
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
return new InputState(this, builder);
}
FramebufferBase* Device::CreateFramebuffer(FramebufferBuilder* builder) { FramebufferBase* Device::CreateFramebuffer(FramebufferBuilder* builder) {
return new Framebuffer(this, builder); return new Framebuffer(this, builder);
} }
PipelineBase* Device::CreatePipeline(PipelineBuilder* builder) { InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
return new Pipeline(this, builder); return new InputState(this, builder);
} }
PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) { PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) {
return new PipelineLayout(this, builder); return new PipelineLayout(this, builder);
@ -243,6 +244,9 @@ namespace d3d12 {
RenderPassBase* Device::CreateRenderPass(RenderPassBuilder* builder) { RenderPassBase* Device::CreateRenderPass(RenderPassBuilder* builder) {
return new RenderPass(this, builder); return new RenderPass(this, builder);
} }
RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) {
return new RenderPipeline(builder);
}
SamplerBase* Device::CreateSampler(SamplerBuilder* builder) { SamplerBase* Device::CreateSampler(SamplerBuilder* builder) {
return new Sampler(builder); return new Sampler(builder);
} }

View File

@ -17,18 +17,9 @@
#include "nxt/nxtcpp.h" #include "nxt/nxtcpp.h"
#include "backend/Buffer.h"
#include "backend/BindGroup.h"
#include "backend/BindGroupLayout.h"
#include "backend/Device.h"
#include "backend/Framebuffer.h"
#include "backend/DepthStencilState.h" #include "backend/DepthStencilState.h"
#include "backend/InputState.h" #include "backend/Device.h"
#include "backend/PipelineLayout.h"
#include "backend/Queue.h"
#include "backend/RenderPass.h" #include "backend/RenderPass.h"
#include "backend/Sampler.h"
#include "backend/Texture.h"
#include "backend/ToBackend.h" #include "backend/ToBackend.h"
#include "backend/d3d12/d3d12_platform.h" #include "backend/d3d12/d3d12_platform.h"
@ -41,18 +32,19 @@ namespace d3d12 {
class Buffer; class Buffer;
class BufferView; class BufferView;
class CommandBuffer; class CommandBuffer;
class ComputePipeline;
class DepthStencilState; class DepthStencilState;
class Device; class Device;
class Framebuffer;
class InputState; class InputState;
class Pipeline;
class PipelineLayout; class PipelineLayout;
class Queue; class Queue;
class RenderPass;
class RenderPipeline;
class Sampler; class Sampler;
class ShaderModule; class ShaderModule;
class Texture; class Texture;
class TextureView; class TextureView;
class Framebuffer;
class RenderPass;
class CommandAllocatorManager; class CommandAllocatorManager;
class DescriptorHeapAllocator; class DescriptorHeapAllocator;
@ -66,18 +58,19 @@ namespace d3d12 {
using BufferType = Buffer; using BufferType = Buffer;
using BufferViewType = BufferView; using BufferViewType = BufferView;
using CommandBufferType = CommandBuffer; using CommandBufferType = CommandBuffer;
using ComputePipelineType = ComputePipeline;
using DepthStencilStateType = DepthStencilState; using DepthStencilStateType = DepthStencilState;
using DeviceType = Device; using DeviceType = Device;
using FramebufferType = Framebuffer;
using InputStateType = InputState; using InputStateType = InputState;
using PipelineType = Pipeline;
using PipelineLayoutType = PipelineLayout; using PipelineLayoutType = PipelineLayout;
using QueueType = Queue; using QueueType = Queue;
using RenderPassType = RenderPass;
using RenderPipelineType = RenderPipeline;
using SamplerType = Sampler; using SamplerType = Sampler;
using ShaderModuleType = ShaderModule; using ShaderModuleType = ShaderModule;
using TextureType = Texture; using TextureType = Texture;
using TextureViewType = TextureView; using TextureViewType = TextureView;
using FramebufferType = Framebuffer;
using RenderPassType = RenderPass;
}; };
template<typename T> template<typename T>
@ -98,13 +91,14 @@ namespace d3d12 {
BufferBase* CreateBuffer(BufferBuilder* builder) override; BufferBase* CreateBuffer(BufferBuilder* builder) override;
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override; BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override; CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override; DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override; FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override;
PipelineBase* CreatePipeline(PipelineBuilder* builder) override; InputStateBase* CreateInputState(InputStateBuilder* builder) override;
PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override; PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override;
QueueBase* CreateQueue(QueueBuilder* builder) override; QueueBase* CreateQueue(QueueBuilder* builder) override;
RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) override; RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) override;
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
SamplerBase* CreateSampler(SamplerBuilder* builder) override; SamplerBase* CreateSampler(SamplerBuilder* builder) override;
ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override; ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override;
TextureBase* CreateTexture(TextureBuilder* builder) override; TextureBase* CreateTexture(TextureBuilder* builder) override;

View File

@ -17,11 +17,12 @@
#include "backend/d3d12/BindGroupLayoutD3D12.h" #include "backend/d3d12/BindGroupLayoutD3D12.h"
#include "backend/d3d12/BufferD3D12.h" #include "backend/d3d12/BufferD3D12.h"
#include "backend/d3d12/CommandBufferD3D12.h" #include "backend/d3d12/CommandBufferD3D12.h"
#include "backend/d3d12/ComputePipelineD3D12.h"
#include "backend/d3d12/FramebufferD3D12.h" #include "backend/d3d12/FramebufferD3D12.h"
#include "backend/d3d12/InputStateD3D12.h" #include "backend/d3d12/InputStateD3D12.h"
#include "backend/d3d12/PipelineD3D12.h"
#include "backend/d3d12/PipelineLayoutD3D12.h" #include "backend/d3d12/PipelineLayoutD3D12.h"
#include "backend/d3d12/QueueD3D12.h" #include "backend/d3d12/QueueD3D12.h"
#include "backend/d3d12/RenderPipelineD3D12.h"
#include "backend/d3d12/SamplerD3D12.h" #include "backend/d3d12/SamplerD3D12.h"
#include "backend/d3d12/ShaderModuleD3D12.h" #include "backend/d3d12/ShaderModuleD3D12.h"
#include "backend/d3d12/TextureD3D12.h" #include "backend/d3d12/TextureD3D12.h"

View File

@ -1,174 +0,0 @@
// 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 "backend/d3d12/PipelineD3D12.h"
#include "backend/d3d12/D3D12Backend.h"
#include "backend/d3d12/InputStateD3D12.h"
#include "backend/d3d12/ShaderModuleD3D12.h"
#include "backend/d3d12/PipelineLayoutD3D12.h"
#include "common/Assert.h"
#include <d3dcompiler.h>
using Microsoft::WRL::ComPtr;
namespace backend {
namespace d3d12 {
Pipeline::Pipeline(Device* device, PipelineBuilder* builder) : PipelineBase(builder), device(device) {
uint32_t compileFlags = 0;
#if defined(_DEBUG)
// Enable better shader debugging with the graphics debugging tools.
compileFlags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
#endif
// SPRIV-cross does matrix multiplication expecting row major matrices
compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;
if (IsCompute()) {
const auto& module = ToBackend(builder->GetStageInfo(nxt::ShaderStage::Compute).module);
const auto& entryPoint = builder->GetStageInfo(nxt::ShaderStage::Compute).entryPoint;
const auto& hlslSource = module->GetHLSLSource();
ComPtr<ID3DBlob> compiledShader;
ComPtr<ID3DBlob> errors;
if(FAILED(D3DCompile(
hlslSource.c_str(),
hlslSource.length(),
nullptr,
{ nullptr },
nullptr,
entryPoint.c_str(),
"cs_5_0",
compileFlags,
0,
&compiledShader,
&errors
))) {
printf("%s\n", reinterpret_cast<char*>(errors->GetBufferPointer()));
ASSERT(false);
}
D3D12_COMPUTE_PIPELINE_STATE_DESC descriptor = {};
descriptor.pRootSignature = ToBackend(GetLayout())->GetRootSignature().Get();
descriptor.CS.pShaderBytecode = compiledShader->GetBufferPointer();
descriptor.CS.BytecodeLength = compiledShader->GetBufferSize();
device->GetD3D12Device()->CreateComputePipelineState(&descriptor, IID_PPV_ARGS(&computePipelineState));
} else {
D3D12_GRAPHICS_PIPELINE_STATE_DESC descriptor = {};
PerStage<ComPtr<ID3DBlob>> compiledShader;
ComPtr<ID3DBlob> errors;
for (auto stage : IterateStages(GetStageMask())) {
const auto& module = ToBackend(builder->GetStageInfo(stage).module);
const auto& entryPoint = builder->GetStageInfo(stage).entryPoint;
const auto& hlslSource = module->GetHLSLSource();
const char* compileTarget = nullptr;
D3D12_SHADER_BYTECODE* shader = nullptr;
switch (stage) {
case nxt::ShaderStage::Vertex:
shader = &descriptor.VS;
compileTarget = "vs_5_1";
break;
case nxt::ShaderStage::Fragment:
shader = &descriptor.PS;
compileTarget = "ps_5_1";
break;
case nxt::ShaderStage::Compute:
UNREACHABLE();
break;
}
if(FAILED(D3DCompile(
hlslSource.c_str(),
hlslSource.length(),
nullptr,
nullptr,
nullptr,
entryPoint.c_str(),
compileTarget,
compileFlags,
0,
&compiledShader[stage],
&errors
))) {
printf("%s\n", reinterpret_cast<char*>(errors->GetBufferPointer()));
ASSERT(false);
}
if (shader != nullptr) {
shader->pShaderBytecode = compiledShader[stage]->GetBufferPointer();
shader->BytecodeLength = compiledShader[stage]->GetBufferSize();
}
}
PipelineLayout* layout = ToBackend(GetLayout());
descriptor.pRootSignature = layout->GetRootSignature().Get();
// D3D12 logs warnings if any empty input state is used
InputState* inputState = ToBackend(GetInputState());
if (inputState->GetAttributesSetMask().any()) {
descriptor.InputLayout = inputState->GetD3D12InputLayoutDescriptor();
}
descriptor.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
descriptor.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
descriptor.RasterizerState.FrontCounterClockwise = FALSE;
descriptor.RasterizerState.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
descriptor.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
descriptor.RasterizerState.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
descriptor.RasterizerState.DepthClipEnable = TRUE;
descriptor.RasterizerState.MultisampleEnable = FALSE;
descriptor.RasterizerState.AntialiasedLineEnable = FALSE;
descriptor.RasterizerState.ForcedSampleCount = 0;
descriptor.RasterizerState.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
descriptor.BlendState.AlphaToCoverageEnable = FALSE;
descriptor.BlendState.IndependentBlendEnable = FALSE;
descriptor.BlendState.RenderTarget[0].BlendEnable = FALSE;
descriptor.BlendState.RenderTarget[0].LogicOpEnable = FALSE;
descriptor.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_ONE;
descriptor.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_ZERO;
descriptor.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
descriptor.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE;
descriptor.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO;
descriptor.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
descriptor.BlendState.RenderTarget[0].LogicOp = D3D12_LOGIC_OP_NOOP;
descriptor.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
descriptor.DepthStencilState.DepthEnable = false;
descriptor.DepthStencilState.StencilEnable = false;
descriptor.SampleMask = UINT_MAX;
descriptor.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
descriptor.NumRenderTargets = 1;
descriptor.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
descriptor.SampleDesc.Count = 1;
ASSERT_SUCCESS(device->GetD3D12Device()->CreateRenderPipelineState(&descriptor, IID_PPV_ARGS(&renderPipelineState)));
}
}
ComPtr<ID3D12PipelineState> Pipeline::GetRenderPipelineState() {
return renderPipelineState;
}
}
}

View File

@ -0,0 +1,140 @@
// 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 "backend/d3d12/RenderPipelineD3D12.h"
#include "backend/d3d12/D3D12Backend.h"
#include "backend/d3d12/InputStateD3D12.h"
#include "backend/d3d12/ShaderModuleD3D12.h"
#include "backend/d3d12/PipelineLayoutD3D12.h"
#include "common/Assert.h"
#include <d3dcompiler.h>
namespace backend {
namespace d3d12 {
RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder)
: RenderPipelineBase(builder) {
uint32_t compileFlags = 0;
#if defined(_DEBUG)
// Enable better shader debugging with the graphics debugging tools.
compileFlags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
#endif
// SPRIV-cross does matrix multiplication expecting row major matrices
compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;
D3D12_GRAPHICS_PIPELINE_STATE_DESC descriptor = {};
PerStage<ComPtr<ID3DBlob>> compiledShader;
ComPtr<ID3DBlob> errors;
for (auto stage : IterateStages(GetStageMask())) {
const auto& module = ToBackend(builder->GetStageInfo(stage).module);
const auto& entryPoint = builder->GetStageInfo(stage).entryPoint;
const auto& hlslSource = module->GetHLSLSource();
const char* compileTarget = nullptr;
D3D12_SHADER_BYTECODE* shader = nullptr;
switch (stage) {
case nxt::ShaderStage::Vertex:
shader = &descriptor.VS;
compileTarget = "vs_5_1";
break;
case nxt::ShaderStage::Fragment:
shader = &descriptor.PS;
compileTarget = "ps_5_1";
break;
case nxt::ShaderStage::Compute:
UNREACHABLE();
break;
}
if(FAILED(D3DCompile(
hlslSource.c_str(),
hlslSource.length(),
nullptr,
nullptr,
nullptr,
entryPoint.c_str(),
compileTarget,
compileFlags,
0,
&compiledShader[stage],
&errors
))) {
printf("%s\n", reinterpret_cast<char*>(errors->GetBufferPointer()));
ASSERT(false);
}
if (shader != nullptr) {
shader->pShaderBytecode = compiledShader[stage]->GetBufferPointer();
shader->BytecodeLength = compiledShader[stage]->GetBufferSize();
}
}
PipelineLayout* layout = ToBackend(GetLayout());
descriptor.pRootSignature = layout->GetRootSignature().Get();
// D3D12 logs warnings if any empty input state is used
InputState* inputState = ToBackend(GetInputState());
if (inputState->GetAttributesSetMask().any()) {
descriptor.InputLayout = inputState->GetD3D12InputLayoutDescriptor();
}
descriptor.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
descriptor.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
descriptor.RasterizerState.FrontCounterClockwise = FALSE;
descriptor.RasterizerState.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
descriptor.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
descriptor.RasterizerState.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
descriptor.RasterizerState.DepthClipEnable = TRUE;
descriptor.RasterizerState.MultisampleEnable = FALSE;
descriptor.RasterizerState.AntialiasedLineEnable = FALSE;
descriptor.RasterizerState.ForcedSampleCount = 0;
descriptor.RasterizerState.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
descriptor.BlendState.AlphaToCoverageEnable = FALSE;
descriptor.BlendState.IndependentBlendEnable = FALSE;
descriptor.BlendState.RenderTarget[0].BlendEnable = FALSE;
descriptor.BlendState.RenderTarget[0].LogicOpEnable = FALSE;
descriptor.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_ONE;
descriptor.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_ZERO;
descriptor.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
descriptor.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE;
descriptor.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO;
descriptor.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
descriptor.BlendState.RenderTarget[0].LogicOp = D3D12_LOGIC_OP_NOOP;
descriptor.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
descriptor.DepthStencilState.DepthEnable = false;
descriptor.DepthStencilState.StencilEnable = false;
descriptor.SampleMask = UINT_MAX;
descriptor.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
descriptor.NumRenderTargets = 1;
descriptor.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
descriptor.SampleDesc.Count = 1;
Device* device = ToBackend(builder->GetDevice());
ASSERT_SUCCESS(device->GetD3D12Device()->CreateGraphicsPipelineState(&descriptor, IID_PPV_ARGS(&pipelineState)));
}
ComPtr<ID3D12PipelineState> RenderPipeline::GetPipelineState() {
return pipelineState;
}
}
}

View File

@ -12,33 +12,27 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef BACKEND_D3D12_PIPELINED3D12_H_ #ifndef BACKEND_D3D12_RENDERPIPELINED3D12_H_
#define BACKEND_D3D12_PIPELINED3D12_H_ #define BACKEND_D3D12_RENDERPIPELINED3D12_H_
#include "backend/Pipeline.h" #include "backend/RenderPipeline.h"
#include "backend/d3d12/d3d12_platform.h" #include "backend/d3d12/d3d12_platform.h"
namespace backend { namespace backend {
namespace d3d12 { namespace d3d12 {
class Device; class RenderPipeline : public RenderPipelineBase {
class ShaderModule;
class Pipeline : public PipelineBase {
public: public:
Pipeline(Device* device, PipelineBuilder* builder); RenderPipeline(RenderPipelineBuilder* builder);
ComPtr<ID3D12PipelineState> GetRenderPipelineState(); ComPtr<ID3D12PipelineState> GetPipelineState();
private: private:
Device* device; ComPtr<ID3D12PipelineState> pipelineState;
ComPtr<ID3D12PipelineState> renderPipelineState;
ComPtr<ID3D12PipelineState> computePipelineState;
}; };
} }
} }
#endif // BACKEND_D3D12_PIPELINED3D12_H_ #endif // BACKEND_D3D12_RENDERPIPELINED3D12_H_