Split Pipeline in Render and Compute, D3D12 part
This commit is contained in:
parent
66ff447216
commit
136cae5ee2
|
@ -215,6 +215,8 @@ if (NXT_ENABLE_D3D12)
|
|||
${D3D12_DIR}/CommandAllocatorManager.h
|
||||
${D3D12_DIR}/CommandBufferD3D12.cpp
|
||||
${D3D12_DIR}/CommandBufferD3D12.h
|
||||
${D3D12_DIR}/ComputePipelineD3D12.cpp
|
||||
${D3D12_DIR}/ComputePipelineD3D12.h
|
||||
${D3D12_DIR}/DescriptorHeapAllocator.cpp
|
||||
${D3D12_DIR}/DescriptorHeapAllocator.h
|
||||
${D3D12_DIR}/D3D12Backend.cpp
|
||||
|
@ -223,12 +225,12 @@ if (NXT_ENABLE_D3D12)
|
|||
${D3D12_DIR}/FramebufferD3D12.h
|
||||
${D3D12_DIR}/InputStateD3D12.cpp
|
||||
${D3D12_DIR}/InputStateD3D12.h
|
||||
${D3D12_DIR}/PipelineD3D12.cpp
|
||||
${D3D12_DIR}/PipelineD3D12.h
|
||||
${D3D12_DIR}/PipelineLayoutD3D12.cpp
|
||||
${D3D12_DIR}/PipelineLayoutD3D12.h
|
||||
${D3D12_DIR}/QueueD3D12.cpp
|
||||
${D3D12_DIR}/QueueD3D12.h
|
||||
${D3D12_DIR}/RenderPipelineD3D12.cpp
|
||||
${D3D12_DIR}/RenderPipelineD3D12.h
|
||||
${D3D12_DIR}/ResourceAllocator.cpp
|
||||
${D3D12_DIR}/ResourceAllocator.h
|
||||
${D3D12_DIR}/ResourceUploader.cpp
|
||||
|
|
|
@ -19,11 +19,12 @@
|
|||
#include "backend/d3d12/BindGroupD3D12.h"
|
||||
#include "backend/d3d12/BindGroupLayoutD3D12.h"
|
||||
#include "backend/d3d12/BufferD3D12.h"
|
||||
#include "backend/d3d12/ComputePipelineD3D12.h"
|
||||
#include "backend/d3d12/DescriptorHeapAllocator.h"
|
||||
#include "backend/d3d12/FramebufferD3D12.h"
|
||||
#include "backend/d3d12/InputStateD3D12.h"
|
||||
#include "backend/d3d12/PipelineD3D12.h"
|
||||
#include "backend/d3d12/PipelineLayoutD3D12.h"
|
||||
#include "backend/d3d12/RenderPipelineD3D12.h"
|
||||
#include "backend/d3d12/ResourceAllocator.h"
|
||||
#include "backend/d3d12/SamplerD3D12.h"
|
||||
#include "backend/d3d12/TextureD3D12.h"
|
||||
|
@ -52,12 +53,17 @@ namespace d3d12 {
|
|||
DescriptorHeapHandle cbvSrvUavGPUDescriptorHeap = {};
|
||||
DescriptorHeapHandle samplerGPUDescriptorHeap = {};
|
||||
std::array<BindGroup*, kMaxBindGroups> bindGroups = {};
|
||||
bool inCompute = false;
|
||||
|
||||
Device* device;
|
||||
|
||||
BindGroupStateTracker(Device* device) : device(device) {
|
||||
}
|
||||
|
||||
void SetInComputePass(bool inCompute) {
|
||||
this->inCompute = inCompute;
|
||||
}
|
||||
|
||||
void TrackSetBindGroup(BindGroup* group, uint32_t index) {
|
||||
if (bindGroups[index] != group) {
|
||||
bindGroups[index] = group;
|
||||
|
@ -70,25 +76,38 @@ namespace d3d12 {
|
|||
}
|
||||
}
|
||||
|
||||
void TrackSetBindInheritedGroup(uint32_t index) {
|
||||
BindGroup* group = bindGroups[index];
|
||||
if (group != nullptr) {
|
||||
TrackSetBindGroup(group, index);
|
||||
void TrackInheritedGroups(PipelineLayout* oldLayout, PipelineLayout* newLayout) {
|
||||
if (oldLayout == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
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) {
|
||||
bindGroups[index] = group;
|
||||
|
||||
PipelineLayout* pipelineLayout = ToBackend(pipeline->GetLayout());
|
||||
uint32_t cbvUavSrvCount = ToBackend(group->GetLayout())->GetCbvUavSrvDescriptorCount();
|
||||
uint32_t samplerCount = ToBackend(group->GetLayout())->GetSamplerDescriptorCount();
|
||||
|
||||
if (cbvUavSrvCount > 0) {
|
||||
uint32_t parameterIndex = pipelineLayout->GetCbvUavSrvRootParameterIndex(index);
|
||||
|
||||
if (pipeline->IsCompute()) {
|
||||
if (inCompute) {
|
||||
commandList->SetComputeRootDescriptorTable(parameterIndex, cbvSrvUavGPUDescriptorHeap.GetGPUHandle(group->GetCbvUavSrvHeapOffset()));
|
||||
} else {
|
||||
commandList->SetGraphicsRootDescriptorTable(parameterIndex, cbvSrvUavGPUDescriptorHeap.GetGPUHandle(group->GetCbvUavSrvHeapOffset()));
|
||||
|
@ -98,7 +117,7 @@ namespace d3d12 {
|
|||
if (samplerCount > 0) {
|
||||
uint32_t parameterIndex = pipelineLayout->GetSamplerRootParameterIndex(index);
|
||||
|
||||
if (pipeline->IsCompute()) {
|
||||
if (inCompute) {
|
||||
commandList->SetComputeRootDescriptorTable(parameterIndex, samplerGPUDescriptorHeap.GetGPUHandle(group->GetSamplerHeapOffset()));
|
||||
} else {
|
||||
commandList->SetGraphicsRootDescriptorTable(parameterIndex, samplerGPUDescriptorHeap.GetGPUHandle(group->GetSamplerHeapOffset()));
|
||||
|
@ -107,10 +126,22 @@ namespace d3d12 {
|
|||
}
|
||||
}
|
||||
|
||||
void SetInheritedBindGroup(ComPtr<ID3D12GraphicsCommandList> commandList, Pipeline* pipeline, uint32_t index) {
|
||||
BindGroup* group = bindGroups[index];
|
||||
if (group != nullptr) {
|
||||
SetBindGroup(commandList, pipeline, group, index, true);
|
||||
void SetInheritedBindGroups(ComPtr<ID3D12GraphicsCommandList> commandList, PipelineLayout* oldLayout, PipelineLayout* newLayout) {
|
||||
if (oldLayout == nullptr) {
|
||||
return;
|
||||
}
|
||||
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;
|
||||
Pipeline* lastPipeline = nullptr;
|
||||
PipelineLayout* lastLayout = nullptr;
|
||||
|
||||
while (commands->NextCommandId(&type)) {
|
||||
switch (type) {
|
||||
case Command::SetPipeline:
|
||||
case Command::SetComputePipeline:
|
||||
{
|
||||
SetPipelineCmd* cmd = commands->NextCommand<SetPipelineCmd>();
|
||||
Pipeline* pipeline = ToBackend(cmd->pipeline).Get();
|
||||
PipelineLayout* layout = ToBackend(pipeline->GetLayout());
|
||||
SetComputePipelineCmd* cmd = commands->NextCommand<SetComputePipelineCmd>();
|
||||
PipelineLayout* layout = ToBackend(cmd->pipeline->GetLayout());
|
||||
bindingTracker->TrackInheritedGroups(lastLayout, layout);
|
||||
lastLayout = layout;
|
||||
}
|
||||
break;
|
||||
|
||||
if (lastLayout) {
|
||||
auto mask = layout->GetBindGroupsLayoutMask();
|
||||
for (uint32_t i = 0; i < kMaxBindGroups; ++i) {
|
||||
// matching bind groups are inherited until they differ
|
||||
if (mask[i] && lastLayout->GetBindGroupLayout(i) == layout->GetBindGroupLayout(i)) {
|
||||
bindingTracker->TrackSetBindInheritedGroup(i);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lastPipeline = pipeline;
|
||||
case Command::SetRenderPipeline:
|
||||
{
|
||||
SetRenderPipelineCmd* cmd = commands->NextCommand<SetRenderPipelineCmd>();
|
||||
PipelineLayout* layout = ToBackend(cmd->pipeline->GetLayout());
|
||||
bindingTracker->TrackInheritedGroups(lastLayout, layout);
|
||||
lastLayout = layout;
|
||||
}
|
||||
break;
|
||||
|
@ -243,7 +268,7 @@ namespace d3d12 {
|
|||
}
|
||||
|
||||
Command type;
|
||||
Pipeline* lastPipeline = nullptr;
|
||||
RenderPipeline* lastRenderPipeline = nullptr;
|
||||
PipelineLayout* lastLayout = nullptr;
|
||||
|
||||
RenderPass* currentRenderPass = nullptr;
|
||||
|
@ -255,6 +280,7 @@ namespace d3d12 {
|
|||
case Command::BeginComputePass:
|
||||
{
|
||||
commands.NextCommand<BeginComputePassCmd>();
|
||||
bindingTracker.SetInComputePass(true);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -351,8 +377,6 @@ namespace d3d12 {
|
|||
case Command::Dispatch:
|
||||
{
|
||||
DispatchCmd* dispatch = commands.NextCommand<DispatchCmd>();
|
||||
|
||||
ASSERT(lastPipeline->IsCompute());
|
||||
commandList->Dispatch(dispatch->x, dispatch->y, dispatch->z);
|
||||
}
|
||||
break;
|
||||
|
@ -389,6 +413,7 @@ namespace d3d12 {
|
|||
case Command::EndComputePass:
|
||||
{
|
||||
commands.NextCommand<EndComputePassCmd>();
|
||||
bindingTracker.SetInComputePass(false);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -405,35 +430,30 @@ namespace d3d12 {
|
|||
}
|
||||
break;
|
||||
|
||||
case Command::SetPipeline:
|
||||
case Command::SetComputePipeline:
|
||||
{
|
||||
SetPipelineCmd* cmd = commands.NextCommand<SetPipelineCmd>();
|
||||
|
||||
Pipeline* pipeline = ToBackend(cmd->pipeline).Get();
|
||||
SetComputePipelineCmd* cmd = commands.NextCommand<SetComputePipelineCmd>();
|
||||
ComputePipeline* pipeline = ToBackend(cmd->pipeline).Get();
|
||||
PipelineLayout* layout = ToBackend(pipeline->GetLayout());
|
||||
|
||||
// TODO
|
||||
if (pipeline->IsCompute()) {
|
||||
}
|
||||
else {
|
||||
commandList->SetGraphicsRootSignature(layout->GetRootSignature().Get());
|
||||
commandList->SetPipelineState(pipeline->GetRenderPipelineState().Get());
|
||||
}
|
||||
// TODO(enga@google.com): Implement compute pipelines
|
||||
bindingTracker.SetInheritedBindGroups(commandList, lastLayout, layout);
|
||||
lastLayout = layout;
|
||||
}
|
||||
break;
|
||||
|
||||
if (lastLayout) {
|
||||
auto mask = layout->GetBindGroupsLayoutMask();
|
||||
for (uint32_t i = 0; i < kMaxBindGroups; ++i) {
|
||||
// matching bind groups are inherited until they differ
|
||||
if (mask[i] && lastLayout->GetBindGroupLayout(i) == layout->GetBindGroupLayout(i)) {
|
||||
bindingTracker.SetInheritedBindGroup(commandList, pipeline, i);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
case Command::SetRenderPipeline:
|
||||
{
|
||||
SetRenderPipelineCmd* cmd = commands.NextCommand<SetRenderPipelineCmd>();
|
||||
RenderPipeline* pipeline = ToBackend(cmd->pipeline).Get();
|
||||
PipelineLayout* layout = ToBackend(pipeline->GetLayout());
|
||||
|
||||
commandList->SetGraphicsRootSignature(layout->GetRootSignature().Get());
|
||||
commandList->SetPipelineState(pipeline->GetPipelineState().Get());
|
||||
|
||||
lastPipeline = pipeline;
|
||||
bindingTracker.SetInheritedBindGroups(commandList, lastLayout, layout);
|
||||
|
||||
lastRenderPipeline = pipeline;
|
||||
lastLayout = layout;
|
||||
}
|
||||
break;
|
||||
|
@ -454,7 +474,7 @@ namespace d3d12 {
|
|||
{
|
||||
SetBindGroupCmd* cmd = commands.NextCommand<SetBindGroupCmd>();
|
||||
BindGroup* group = ToBackend(cmd->group.Get());
|
||||
bindingTracker.SetBindGroup(commandList, lastPipeline, group, cmd->index);
|
||||
bindingTracker.SetBindGroup(commandList, lastLayout, group, cmd->index);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -478,7 +498,7 @@ namespace d3d12 {
|
|||
auto buffers = commands.NextData<Ref<BufferBase>>(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;
|
||||
for (uint32_t i = 0; i < cmd->count; ++i) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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_
|
|
@ -19,12 +19,13 @@
|
|||
#include "backend/d3d12/BufferD3D12.h"
|
||||
#include "backend/d3d12/CommandAllocatorManager.h"
|
||||
#include "backend/d3d12/CommandBufferD3D12.h"
|
||||
#include "backend/d3d12/ComputePipelineD3D12.h"
|
||||
#include "backend/d3d12/DescriptorHeapAllocator.h"
|
||||
#include "backend/d3d12/FramebufferD3D12.h"
|
||||
#include "backend/d3d12/InputStateD3D12.h"
|
||||
#include "backend/d3d12/PipelineD3D12.h"
|
||||
#include "backend/d3d12/PipelineLayoutD3D12.h"
|
||||
#include "backend/d3d12/QueueD3D12.h"
|
||||
#include "backend/d3d12/RenderPipelineD3D12.h"
|
||||
#include "backend/d3d12/ResourceAllocator.h"
|
||||
#include "backend/d3d12/ResourceUploader.h"
|
||||
#include "backend/d3d12/SamplerD3D12.h"
|
||||
|
@ -222,17 +223,17 @@ namespace d3d12 {
|
|||
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
|
||||
return new CommandBuffer(this, builder);
|
||||
}
|
||||
ComputePipelineBase* Device::CreateComputePipeline(ComputePipelineBuilder* builder) {
|
||||
return new ComputePipeline(builder);
|
||||
}
|
||||
DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) {
|
||||
return new DepthStencilState(this, builder);
|
||||
}
|
||||
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
||||
return new InputState(this, builder);
|
||||
}
|
||||
FramebufferBase* Device::CreateFramebuffer(FramebufferBuilder* builder) {
|
||||
return new Framebuffer(this, builder);
|
||||
}
|
||||
PipelineBase* Device::CreatePipeline(PipelineBuilder* builder) {
|
||||
return new Pipeline(this, builder);
|
||||
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
||||
return new InputState(this, builder);
|
||||
}
|
||||
PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) {
|
||||
return new PipelineLayout(this, builder);
|
||||
|
@ -243,6 +244,9 @@ namespace d3d12 {
|
|||
RenderPassBase* Device::CreateRenderPass(RenderPassBuilder* builder) {
|
||||
return new RenderPass(this, builder);
|
||||
}
|
||||
RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) {
|
||||
return new RenderPipeline(builder);
|
||||
}
|
||||
SamplerBase* Device::CreateSampler(SamplerBuilder* builder) {
|
||||
return new Sampler(builder);
|
||||
}
|
||||
|
|
|
@ -17,18 +17,9 @@
|
|||
|
||||
#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/InputState.h"
|
||||
#include "backend/PipelineLayout.h"
|
||||
#include "backend/Queue.h"
|
||||
#include "backend/Device.h"
|
||||
#include "backend/RenderPass.h"
|
||||
#include "backend/Sampler.h"
|
||||
#include "backend/Texture.h"
|
||||
#include "backend/ToBackend.h"
|
||||
|
||||
#include "backend/d3d12/d3d12_platform.h"
|
||||
|
@ -41,18 +32,19 @@ namespace d3d12 {
|
|||
class Buffer;
|
||||
class BufferView;
|
||||
class CommandBuffer;
|
||||
class ComputePipeline;
|
||||
class DepthStencilState;
|
||||
class Device;
|
||||
class Framebuffer;
|
||||
class InputState;
|
||||
class Pipeline;
|
||||
class PipelineLayout;
|
||||
class Queue;
|
||||
class RenderPass;
|
||||
class RenderPipeline;
|
||||
class Sampler;
|
||||
class ShaderModule;
|
||||
class Texture;
|
||||
class TextureView;
|
||||
class Framebuffer;
|
||||
class RenderPass;
|
||||
|
||||
class CommandAllocatorManager;
|
||||
class DescriptorHeapAllocator;
|
||||
|
@ -66,18 +58,19 @@ namespace d3d12 {
|
|||
using BufferType = Buffer;
|
||||
using BufferViewType = BufferView;
|
||||
using CommandBufferType = CommandBuffer;
|
||||
using ComputePipelineType = ComputePipeline;
|
||||
using DepthStencilStateType = DepthStencilState;
|
||||
using DeviceType = Device;
|
||||
using FramebufferType = Framebuffer;
|
||||
using InputStateType = InputState;
|
||||
using PipelineType = Pipeline;
|
||||
using PipelineLayoutType = PipelineLayout;
|
||||
using QueueType = Queue;
|
||||
using RenderPassType = RenderPass;
|
||||
using RenderPipelineType = RenderPipeline;
|
||||
using SamplerType = Sampler;
|
||||
using ShaderModuleType = ShaderModule;
|
||||
using TextureType = Texture;
|
||||
using TextureViewType = TextureView;
|
||||
using FramebufferType = Framebuffer;
|
||||
using RenderPassType = RenderPass;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
@ -98,13 +91,14 @@ namespace d3d12 {
|
|||
BufferBase* CreateBuffer(BufferBuilder* builder) override;
|
||||
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
|
||||
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
|
||||
ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
|
||||
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
|
||||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||
FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override;
|
||||
PipelineBase* CreatePipeline(PipelineBuilder* builder) override;
|
||||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||
PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override;
|
||||
QueueBase* CreateQueue(QueueBuilder* builder) override;
|
||||
RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) override;
|
||||
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
||||
SamplerBase* CreateSampler(SamplerBuilder* builder) override;
|
||||
ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override;
|
||||
TextureBase* CreateTexture(TextureBuilder* builder) override;
|
||||
|
|
|
@ -17,11 +17,12 @@
|
|||
#include "backend/d3d12/BindGroupLayoutD3D12.h"
|
||||
#include "backend/d3d12/BufferD3D12.h"
|
||||
#include "backend/d3d12/CommandBufferD3D12.h"
|
||||
#include "backend/d3d12/ComputePipelineD3D12.h"
|
||||
#include "backend/d3d12/FramebufferD3D12.h"
|
||||
#include "backend/d3d12/InputStateD3D12.h"
|
||||
#include "backend/d3d12/PipelineD3D12.h"
|
||||
#include "backend/d3d12/PipelineLayoutD3D12.h"
|
||||
#include "backend/d3d12/QueueD3D12.h"
|
||||
#include "backend/d3d12/RenderPipelineD3D12.h"
|
||||
#include "backend/d3d12/SamplerD3D12.h"
|
||||
#include "backend/d3d12/ShaderModuleD3D12.h"
|
||||
#include "backend/d3d12/TextureD3D12.h"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -12,33 +12,27 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef BACKEND_D3D12_PIPELINED3D12_H_
|
||||
#define BACKEND_D3D12_PIPELINED3D12_H_
|
||||
#ifndef BACKEND_D3D12_RENDERPIPELINED3D12_H_
|
||||
#define BACKEND_D3D12_RENDERPIPELINED3D12_H_
|
||||
|
||||
#include "backend/Pipeline.h"
|
||||
#include "backend/RenderPipeline.h"
|
||||
|
||||
#include "backend/d3d12/d3d12_platform.h"
|
||||
|
||||
namespace backend {
|
||||
namespace d3d12 {
|
||||
|
||||
class Device;
|
||||
class ShaderModule;
|
||||
|
||||
class Pipeline : public PipelineBase {
|
||||
class RenderPipeline : public RenderPipelineBase {
|
||||
public:
|
||||
Pipeline(Device* device, PipelineBuilder* builder);
|
||||
RenderPipeline(RenderPipelineBuilder* builder);
|
||||
|
||||
ComPtr<ID3D12PipelineState> GetRenderPipelineState();
|
||||
ComPtr<ID3D12PipelineState> GetPipelineState();
|
||||
|
||||
private:
|
||||
Device* device;
|
||||
|
||||
ComPtr<ID3D12PipelineState> renderPipelineState;
|
||||
ComPtr<ID3D12PipelineState> computePipelineState;
|
||||
ComPtr<ID3D12PipelineState> pipelineState;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BACKEND_D3D12_PIPELINED3D12_H_
|
||||
#endif // BACKEND_D3D12_RENDERPIPELINED3D12_H_
|
Loading…
Reference in New Issue