CHelloTriangle working

This commit is contained in:
Austin Eng 2017-06-05 17:22:48 -04:00 committed by Austin Eng
parent eb6d22242a
commit cfeda4d9f2
17 changed files with 748 additions and 113 deletions

View File

@ -214,8 +214,18 @@ if (WIN32)
SetPIC(d3d12_autogen) SetPIC(d3d12_autogen)
list(APPEND BACKEND_SOURCES list(APPEND BACKEND_SOURCES
${D3D12_DIR}/CommandBufferD3D12.cpp
${D3D12_DIR}/CommandBufferD3D12.h
${D3D12_DIR}/D3D12Backend.cpp ${D3D12_DIR}/D3D12Backend.cpp
${D3D12_DIR}/D3D12Backend.h ${D3D12_DIR}/D3D12Backend.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}/ShaderModuleD3D12.cpp
${D3D12_DIR}/ShaderModuleD3D12.h
) )
endif() endif()

View File

@ -36,6 +36,14 @@ namespace backend {
return textureViews[index].Get(); return textureViews[index].Get();
} }
uint32_t FramebufferBase::GetWidth() const {
return width;
}
uint32_t FramebufferBase::GetHeight() const {
return height;
}
// FramebufferBuilder // FramebufferBuilder
enum FramebufferSetProperties { enum FramebufferSetProperties {

View File

@ -32,6 +32,8 @@ namespace backend {
RenderPassBase* GetRenderPass(); RenderPassBase* GetRenderPass();
TextureViewBase* GetTextureView(uint32_t index); TextureViewBase* GetTextureView(uint32_t index);
uint32_t GetWidth() const;
uint32_t GetHeight() const;
private: private:
Ref<RenderPassBase> renderPass; Ref<RenderPassBase> renderPass;

View File

@ -0,0 +1,185 @@
// 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 "CommandBufferD3D12.h"
#include "common/Commands.h"
#include "D3D12Backend.h"
#include "PipelineD3D12.h"
#include "PipelineLayoutD3D12.h"
namespace backend {
namespace d3d12 {
CommandBuffer::CommandBuffer(Device* device, CommandBufferBuilder* builder)
: CommandBufferBase(builder), device(device), commands(builder->AcquireCommands()) {
}
CommandBuffer::~CommandBuffer() {
FreeCommands(&commands);
}
void CommandBuffer::FillCommands(ComPtr<ID3D12GraphicsCommandList> commandList) {
Command type;
Pipeline* lastPipeline = nullptr;
RenderPass* currentRenderPass = nullptr;
Framebuffer* currentFramebuffer = nullptr;
while(commands.NextCommandId(&type)) {
switch (type) {
case Command::AdvanceSubpass:
{
commands.NextCommand<AdvanceSubpassCmd>();
}
break;
case Command::BeginRenderPass:
{
BeginRenderPassCmd* beginRenderPassCmd = commands.NextCommand<BeginRenderPassCmd>();
currentRenderPass = ToBackend(beginRenderPassCmd->renderPass.Get());
currentFramebuffer = ToBackend(beginRenderPassCmd->framebuffer.Get());
float width = (float) currentFramebuffer->GetWidth();
float height = (float) currentFramebuffer->GetHeight();
D3D12_VIEWPORT viewport = { 0.f, 0.f, width, height, 0.f, 1.f };
D3D12_RECT scissorRect = { 0.f, 0.f, width, height };
commandList->RSSetViewports(1, &viewport);
commandList->RSSetScissorRects(1, &scissorRect);
// TODO(enga@google.com): Set the back buffer as the render target only when a new render target is set
D3D12_RESOURCE_BARRIER resourceBarrier;
resourceBarrier.Transition.pResource = device->GetNextRenderTarget().Get();
resourceBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
resourceBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
resourceBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
resourceBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
resourceBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
commandList->ResourceBarrier(1, &resourceBarrier);
commandList->OMSetRenderTargets(1, &device->GetNextRenderTargetDescriptor(), FALSE, nullptr);
}
break;
case Command::CopyBufferToTexture:
{
CopyBufferToTextureCmd* copy = commands.NextCommand<CopyBufferToTextureCmd>();
}
break;
case Command::Dispatch:
{
DispatchCmd* dispatch = commands.NextCommand<DispatchCmd>();
ASSERT(lastPipeline->IsCompute());
commandList->Dispatch(dispatch->x, dispatch->y, dispatch->z);
}
break;
case Command::DrawArrays:
{
DrawArraysCmd* draw = commands.NextCommand<DrawArraysCmd>();
commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
commandList->DrawInstanced(
draw->vertexCount,
draw->instanceCount,
draw->firstVertex,
draw->firstInstance
);
}
break;
case Command::DrawElements:
{
DrawElementsCmd* draw = commands.NextCommand<DrawElementsCmd>();
}
break;
case Command::EndRenderPass:
{
EndRenderPassCmd* cmd = commands.NextCommand<EndRenderPassCmd>();
// TODO(enga@google.com): Present the back buffer only before swap
D3D12_RESOURCE_BARRIER resourceBarrier;
resourceBarrier.Transition.pResource = device->GetNextRenderTarget().Get();
resourceBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
resourceBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
resourceBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
resourceBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
resourceBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
commandList->ResourceBarrier(1, &resourceBarrier);
}
break;
case Command::SetPipeline:
{
SetPipelineCmd* cmd = commands.NextCommand<SetPipelineCmd>();
lastPipeline = ToBackend(cmd->pipeline).Get();
PipelineLayout* pipelineLayout = ToBackend(lastPipeline->GetLayout());
// TODO
if (lastPipeline->IsCompute()) {
} else {
commandList->SetGraphicsRootSignature(pipelineLayout->GetRootSignature().Get());
commandList->SetPipelineState(lastPipeline->GetRenderPipelineState().Get());
}
}
break;
case Command::SetPushConstants:
{
SetPushConstantsCmd* cmd = commands.NextCommand<SetPushConstantsCmd>();
}
break;
case Command::SetStencilReference:
{
SetStencilReferenceCmd* cmd = commands.NextCommand<SetStencilReferenceCmd>();
}
break;
case Command::SetBindGroup:
{
SetBindGroupCmd* cmd = commands.NextCommand<SetBindGroupCmd>();
}
break;
case Command::SetIndexBuffer:
{
SetIndexBufferCmd* cmd = commands.NextCommand<SetIndexBufferCmd>();
}
break;
case Command::SetVertexBuffers:
{
SetVertexBuffersCmd* cmd = commands.NextCommand<SetVertexBuffersCmd>();
}
break;
case Command::TransitionBufferUsage:
{
TransitionBufferUsageCmd* cmd = commands.NextCommand<TransitionBufferUsageCmd>();
}
break;
case Command::TransitionTextureUsage:
{
TransitionTextureUsageCmd* cmd = commands.NextCommand<TransitionTextureUsageCmd>();
}
break;
}
}
}
}
}

View File

@ -0,0 +1,42 @@
// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BACKEND_D3D12_COMMANDBUFFERD3D12_H_
#define BACKEND_D3D12_COMMANDBUFFERD3D12_H_
#include "common/CommandAllocator.h"
#include "common/CommandBuffer.h"
#include "d3d12_platform.h"
namespace backend {
namespace d3d12 {
class Device;
class CommandBuffer : public CommandBufferBase {
public:
CommandBuffer(Device* device, CommandBufferBuilder* builder);
~CommandBuffer();
void FillCommands(ComPtr<ID3D12GraphicsCommandList> commandList);
private:
Device* device;
CommandIterator commands;
};
}
}
#endif // BACKEND_D3D12_COMMANDBUFFERD3D12_H_

View File

@ -14,6 +14,12 @@
#include "D3D12Backend.h" #include "D3D12Backend.h"
#include "CommandBufferD3D12.h"
#include "PipelineD3D12.h"
#include "PipelineLayoutD3D12.h"
#include "QueueD3D12.h"
#include "ShaderModuleD3D12.h"
namespace backend { namespace backend {
namespace d3d12 { namespace d3d12 {
@ -45,19 +51,6 @@ 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)));
// Create an empty root signature.
D3D12_ROOT_SIGNATURE_DESC rootSignatureDescriptor;
rootSignatureDescriptor.NumParameters = 0;
rootSignatureDescriptor.pParameters = nullptr;
rootSignatureDescriptor.NumStaticSamplers = 0;
rootSignatureDescriptor.pStaticSamplers = nullptr;
rootSignatureDescriptor.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
ComPtr<ID3DBlob> signature;
ComPtr<ID3DBlob> error;
ASSERT_SUCCESS(D3D12SerializeRootSignature(&rootSignatureDescriptor, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error));
ASSERT_SUCCESS(d3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&rootSignature)));
} }
Device::~Device() { Device::~Device() {
@ -67,15 +60,11 @@ namespace d3d12 {
return d3d12Device; return d3d12Device;
} }
ComPtr<ID3D12RootSignature> Device::GetRootSignature() {
return rootSignature;
}
ComPtr<ID3D12CommandQueue> Device::GetCommandQueue() { ComPtr<ID3D12CommandQueue> Device::GetCommandQueue() {
return commandQueue; return commandQueue;
} }
Microsoft::WRL::ComPtr<ID3D12Resource> Device::GetNextRenderTarget() { ComPtr<ID3D12Resource> Device::GetNextRenderTarget() {
return renderTargetResource; return renderTargetResource;
} }
@ -170,12 +159,6 @@ namespace d3d12 {
: BufferViewBase(builder), device(device) { : BufferViewBase(builder), device(device) {
} }
// CommandBuffer
CommandBuffer::CommandBuffer(Device* device, CommandBufferBuilder* builder)
: CommandBufferBase(builder), device(device) {
}
// DepthStencilState // DepthStencilState
DepthStencilState::DepthStencilState(Device* device, DepthStencilStateBuilder* builder) DepthStencilState::DepthStencilState(Device* device, DepthStencilStateBuilder* builder)
@ -194,28 +177,6 @@ namespace d3d12 {
: InputStateBase(builder), device(device) { : InputStateBase(builder), device(device) {
} }
// Pipeline
Pipeline::Pipeline(Device* device, PipelineBuilder* builder)
: PipelineBase(builder), device(device) {
}
// PipelineLayout
PipelineLayout::PipelineLayout(Device* device, PipelineLayoutBuilder* builder)
: PipelineLayoutBase(builder), device(device) {
}
// Queue
Queue::Queue(Device* device, QueueBuilder* builder)
: QueueBase(builder), device(device) {
}
void Queue::Submit(uint32_t numCommands, CommandBuffer* const * commands) {
}
// RenderPass // RenderPass
RenderPass::RenderPass(Device* device, RenderPassBuilder* builder) RenderPass::RenderPass(Device* device, RenderPassBuilder* builder)
@ -228,12 +189,6 @@ namespace d3d12 {
: SamplerBase(builder), device(device) { : SamplerBase(builder), device(device) {
} }
// ShaderModule
ShaderModule::ShaderModule(Device* device, ShaderModuleBuilder* builder)
: ShaderModuleBase(builder), device(device) {
}
// Texture // Texture
Texture::Texture(Device* device, TextureBuilder* builder) Texture::Texture(Device* device, TextureBuilder* builder)

View File

@ -20,17 +20,14 @@
#include "common/Buffer.h" #include "common/Buffer.h"
#include "common/BindGroup.h" #include "common/BindGroup.h"
#include "common/BindGroupLayout.h" #include "common/BindGroupLayout.h"
#include "common/CommandBuffer.h"
#include "common/Device.h" #include "common/Device.h"
#include "common/Framebuffer.h" #include "common/Framebuffer.h"
#include "common/DepthStencilState.h" #include "common/DepthStencilState.h"
#include "common/InputState.h" #include "common/InputState.h"
#include "common/Pipeline.h"
#include "common/PipelineLayout.h" #include "common/PipelineLayout.h"
#include "common/Queue.h" #include "common/Queue.h"
#include "common/RenderPass.h" #include "common/RenderPass.h"
#include "common/Sampler.h" #include "common/Sampler.h"
#include "common/ShaderModule.h"
#include "common/Texture.h" #include "common/Texture.h"
#include "common/ToBackend.h" #include "common/ToBackend.h"
@ -85,7 +82,7 @@ namespace d3d12 {
// Definition of backend types // Definition of backend types
class Device : public DeviceBase { class Device : public DeviceBase {
public: public:
Device(Microsoft::WRL::ComPtr<ID3D12Device> d3d12Device); Device(ComPtr<ID3D12Device> d3d12Device);
~Device(); ~Device();
BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override; BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
@ -105,23 +102,21 @@ namespace d3d12 {
TextureBase* CreateTexture(TextureBuilder* builder) override; TextureBase* CreateTexture(TextureBuilder* builder) override;
TextureViewBase* CreateTextureView(TextureViewBuilder* builder) override; TextureViewBase* CreateTextureView(TextureViewBuilder* builder) override;
Microsoft::WRL::ComPtr<ID3D12Device> GetD3D12Device(); ComPtr<ID3D12Device> GetD3D12Device();
Microsoft::WRL::ComPtr<ID3D12RootSignature> GetRootSignature(); ComPtr<ID3D12CommandQueue> GetCommandQueue();
Microsoft::WRL::ComPtr<ID3D12CommandQueue> GetCommandQueue(); ComPtr<ID3D12Resource> GetNextRenderTarget();
Microsoft::WRL::ComPtr<ID3D12Resource> GetNextRenderTarget();
D3D12_CPU_DESCRIPTOR_HANDLE GetNextRenderTargetDescriptor(); D3D12_CPU_DESCRIPTOR_HANDLE GetNextRenderTargetDescriptor();
void SetNextRenderTarget(Microsoft::WRL::ComPtr<ID3D12Resource> renderTargetResource, D3D12_CPU_DESCRIPTOR_HANDLE renderTargetDescriptor); void SetNextRenderTarget(ComPtr<ID3D12Resource> renderTargetResource, D3D12_CPU_DESCRIPTOR_HANDLE renderTargetDescriptor);
// NXT API // NXT API
void Reference(); void Reference();
void Release(); void Release();
private: private:
Microsoft::WRL::ComPtr<ID3D12Device> d3d12Device; ComPtr<ID3D12Device> d3d12Device;
Microsoft::WRL::ComPtr<ID3D12CommandQueue> commandQueue; ComPtr<ID3D12CommandQueue> commandQueue;
Microsoft::WRL::ComPtr<ID3D12RootSignature> rootSignature; ComPtr<ID3D12Resource> renderTargetResource;
Microsoft::WRL::ComPtr<ID3D12Resource> renderTargetResource;
D3D12_CPU_DESCRIPTOR_HANDLE renderTargetDescriptor; D3D12_CPU_DESCRIPTOR_HANDLE renderTargetDescriptor;
}; };
@ -160,14 +155,6 @@ namespace d3d12 {
Device* device; Device* device;
}; };
class CommandBuffer : public CommandBufferBase {
public:
CommandBuffer(Device* device, CommandBufferBuilder* buidler);
private:
Device* device;
};
class Framebuffer : public FramebufferBase { class Framebuffer : public FramebufferBase {
public: public:
Framebuffer(Device* device, FramebufferBuilder* builder); Framebuffer(Device* device, FramebufferBuilder* builder);
@ -192,33 +179,6 @@ namespace d3d12 {
Device* device; Device* device;
}; };
class Pipeline : public PipelineBase {
public:
Pipeline(Device* device, PipelineBuilder* buidler);
private:
Device* device;
};
class PipelineLayout : public PipelineLayoutBase {
public:
PipelineLayout(Device* device, PipelineLayoutBuilder* builder);
private:
Device* device;
};
class Queue : public QueueBase {
public:
Queue(Device* device, QueueBuilder* builder);
// NXT API
void Submit(uint32_t numCommands, CommandBuffer* const * commands);
private:
Device* device;
};
class RenderPass : public RenderPassBase { class RenderPass : public RenderPassBase {
public: public:
RenderPass(Device* device, RenderPassBuilder* builder); RenderPass(Device* device, RenderPassBuilder* builder);
@ -235,14 +195,6 @@ namespace d3d12 {
Device* device; Device* device;
}; };
class ShaderModule : public ShaderModuleBase {
public:
ShaderModule(Device* device, ShaderModuleBuilder* builder);
private:
Device* device;
};
class Texture : public TextureBase { class Texture : public TextureBase {
public: public:
Texture(Device* device, TextureBuilder* builder); Texture(Device* device, TextureBuilder* builder);

View File

@ -13,3 +13,8 @@
// limitations under the License. // limitations under the License.
#include "D3D12Backend.h" #include "D3D12Backend.h"
#include "CommandBufferD3D12.h"
#include "PipelineD3D12.h"
#include "PipelineLayoutD3D12.h"
#include "QueueD3D12.h"
#include "ShaderModuleD3D12.h"

View File

@ -0,0 +1,162 @@
// 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 "PipelineD3D12.h"
#include "D3D12Backend.h"
#include "ShaderModuleD3D12.h"
#include "PipelineLayoutD3D12.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
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", 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_0";
break;
case nxt::ShaderStage::Fragment:
shader = &descriptor.PS;
compileTarget = "ps_5_0";
break;
case nxt::ShaderStage::Compute:
ASSERT(false);
break;
}
if(FAILED(D3DCompile(
hlslSource.c_str(),
hlslSource.length(),
nullptr,
nullptr,
nullptr,
entryPoint.c_str(),
compileTarget,
compileFlags,
0,
&compiledShader[stage],
&errors
))) {
printf("%s\n", errors->GetBufferPointer());
ASSERT(false);
}
if (shader != nullptr) {
shader->pShaderBytecode = compiledShader[stage]->GetBufferPointer();
shader->BytecodeLength = compiledShader[stage]->GetBufferSize();
}
}
descriptor.pRootSignature = ToBackend(GetLayout())->GetRootSignature().Get();
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()->CreateGraphicsPipelineState(&descriptor, IID_PPV_ARGS(&renderPipelineState)));
}
}
ComPtr<ID3D12PipelineState> Pipeline::GetRenderPipelineState() {
return renderPipelineState;
}
}
}

View File

@ -0,0 +1,44 @@
// 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_PIPELINED3D12_H_
#define BACKEND_D3D12_PIPELINED3D12_H_
#include "common/Pipeline.h"
#include "d3d12_platform.h"
namespace backend {
namespace d3d12 {
class Device;
class ShaderModule;
class Pipeline : public PipelineBase {
public:
Pipeline(Device* device, PipelineBuilder* builder);
ComPtr<ID3D12PipelineState> GetRenderPipelineState();
private:
Device* device;
ComPtr<ID3D12PipelineState> renderPipelineState;
ComPtr<ID3D12PipelineState> computePipelineState;
};
}
}
#endif // BACKEND_D3D12_PIPELINED3D12_H_

View File

@ -0,0 +1,46 @@
// 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 "PipelineLayoutD3D12.h"
#include "D3D12Backend.h"
using Microsoft::WRL::ComPtr;
namespace backend {
namespace d3d12 {
PipelineLayout::PipelineLayout(Device* device, PipelineLayoutBuilder* builder)
: PipelineLayoutBase(builder), device(device) {
// Create an empty root signature.
D3D12_ROOT_SIGNATURE_DESC rootSignatureDescriptor;
rootSignatureDescriptor.NumParameters = 0;
rootSignatureDescriptor.pParameters = nullptr;
rootSignatureDescriptor.NumStaticSamplers = 0;
rootSignatureDescriptor.pStaticSamplers = nullptr;
rootSignatureDescriptor.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
ComPtr<ID3DBlob> signature;
ComPtr<ID3DBlob> error;
ASSERT_SUCCESS(D3D12SerializeRootSignature(&rootSignatureDescriptor, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error));
ASSERT_SUCCESS(device->GetD3D12Device()->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&rootSignature)));
}
ComPtr<ID3D12RootSignature> PipelineLayout::GetRootSignature() {
return rootSignature;
}
}
}

View File

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

View File

@ -0,0 +1,52 @@
// 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 "QueueD3D12.h"
#include "D3D12Backend.h"
#include "CommandBufferD3D12.h"
namespace backend {
namespace d3d12 {
Queue::Queue(Device* device, QueueBuilder* builder)
: QueueBase(builder), device(device) {
ASSERT_SUCCESS(device->GetD3D12Device()->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&commandAllocator)));
ASSERT_SUCCESS(device->GetD3D12Device()->CreateCommandList(
0,
D3D12_COMMAND_LIST_TYPE_DIRECT,
commandAllocator.Get(),
nullptr,
IID_PPV_ARGS(&commandList)
));
ASSERT_SUCCESS(commandList->Close());
}
void Queue::Submit(uint32_t numCommands, CommandBuffer* const * commands) {
ASSERT_SUCCESS(commandAllocator->Reset());
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);
}
}
}

View File

@ -0,0 +1,45 @@
// 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_QUEUED3D12_H_
#define BACKEND_D3D12_QUEUED3D12_H_
#include "common/Queue.h"
#include "d3d12_platform.h"
namespace backend {
namespace d3d12 {
class Device;
class CommandBuffer;
class Queue : public QueueBase {
public:
Queue(Device* device, QueueBuilder* builder);
// NXT API
void Submit(uint32_t numCommands, CommandBuffer* const * commands);
private:
Device* device;
ComPtr<ID3D12CommandAllocator> commandAllocator;
ComPtr<ID3D12GraphicsCommandList> commandList;
};
}
}
#endif // BACKEND_D3D12_QUEUED3D12_H_

View File

@ -0,0 +1,43 @@
// 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 "ShaderModuleD3D12.h"
#include <spirv-cross/spirv_hlsl.hpp>
namespace backend {
namespace d3d12 {
ShaderModule::ShaderModule(Device* device, ShaderModuleBuilder* builder)
: ShaderModuleBase(builder), device(device) {
spirv_cross::CompilerHLSL compiler(builder->AcquireSpirv());
spirv_cross::CompilerHLSL::Options options;
options.shader_model = 40;
options.flip_vert_y = false;
options.fixup_clipspace = true;
compiler.set_options(options);
ExtractSpirvInfo(compiler);
hlslSource = compiler.compile();
}
const std::string& ShaderModule::GetHLSLSource() const {
return hlslSource;
}
}
}

View File

@ -0,0 +1,40 @@
// 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_SHADERMODULED3D12_H_
#define BACKEND_D3D12_SHADERMODULED3D12_H_
#include "common/ShaderModule.h"
namespace backend {
namespace d3d12 {
class Device;
class ShaderModule : public ShaderModuleBase {
public:
ShaderModule(Device* device, ShaderModuleBuilder* builder);
const std::string& GetHLSLSource() const;
private:
Device* device;
std::string hlslSource;
};
}
}
#endif // BACKEND_D3D12_SHADERMODULED3D12_H_

View File

@ -259,7 +259,8 @@ namespace metal {
id<MTLComputeCommandEncoder> compute = nil; id<MTLComputeCommandEncoder> compute = nil;
id<MTLRenderCommandEncoder> render = nil; id<MTLRenderCommandEncoder> render = nil;
BeginRenderPassCmd* currentRenderPass = nullptr; RenderPass* currentRenderPass = nullptr;
Framebuffer* currentFramebuffer = nullptr;
void FinishEncoders() { void FinishEncoders() {
ASSERT(render == nil); ASSERT(render == nil);
@ -293,8 +294,7 @@ namespace metal {
render = nil; render = nil;
} }
const auto& info = currentRenderPass->renderPass->GetSubpassInfo(subpass); const auto& info = currentRenderPass->GetSubpassInfo(subpass);
auto& framebuffer = currentRenderPass->framebuffer;
MTLRenderPassDescriptor* descriptor = [MTLRenderPassDescriptor renderPassDescriptor]; MTLRenderPassDescriptor* descriptor = [MTLRenderPassDescriptor renderPassDescriptor];
bool usingBackbuffer = false; // HACK(kainino@chromium.org): workaround for not having depth attachments bool usingBackbuffer = false; // HACK(kainino@chromium.org): workaround for not having depth attachments
@ -305,7 +305,7 @@ namespace metal {
// falls back to the 'back buffer' but this should go away // falls back to the 'back buffer' but this should go away
// when we have WSI. // when we have WSI.
id<MTLTexture> texture = nil; id<MTLTexture> texture = nil;
if (auto textureView = framebuffer->GetTextureView(attachment)) { if (auto textureView = currentFramebuffer->GetTextureView(attachment)) {
texture = ToBackend(textureView->GetTexture())->GetMTLTexture(); texture = ToBackend(textureView->GetTexture())->GetMTLTexture();
} else { } else {
texture = device->GetCurrentTexture(); texture = device->GetCurrentTexture();
@ -359,7 +359,9 @@ namespace metal {
case Command::BeginRenderPass: case Command::BeginRenderPass:
{ {
encoders.currentRenderPass = commands.NextCommand<BeginRenderPassCmd>(); BeginRenderPassCmd* beginRenderPassCmd = commands.NextCommand<BeginRenderPassCmd>();
encoders.currentRenderPass = ToBackend(beginRenderPassCmd->renderPass.Get());
encoders.currentFramebuffer = ToBackend(beginRenderPassCmd->framebuffer.Get());
encoders.FinishEncoders(); encoders.FinishEncoders();
currentSubpass = 0; currentSubpass = 0;
encoders.BeginSubpass(commandBuffer, currentSubpass); encoders.BeginSubpass(commandBuffer, currentSubpass);