diff --git a/generator/main.py b/generator/main.py index d68f0b4056..62ad73daa8 100644 --- a/generator/main.py +++ b/generator/main.py @@ -420,30 +420,18 @@ def main(): } ] - if 'opengl' in targets: - opengl_params = { - 'namespace': 'opengl', - } - renders.append(FileRender('BackendProcTable.cpp', 'opengl/ProcTable.cpp', base_backend_params + [opengl_params])) + for backend in ['d3d12', 'metal', 'null', 'opengl', 'vulkan']: + if not backend in targets: + continue - if 'metal' in targets: - metal_params = { - 'namespace': 'metal', - } - renders.append(FileRender('BackendProcTable.cpp', 'metal/ProcTable.mm', base_backend_params + [metal_params])) + extension = 'cpp' + if backend == 'metal': + extension = 'mm' - if 'd3d12' in targets: - d3d12_params = { - 'namespace': 'd3d12', + backend_params = { + 'namespace': backend, } - renders.append(FileRender('BackendProcTable.cpp', 'd3d12/ProcTable.cpp', base_backend_params + [d3d12_params])) - - if 'null' in targets: - null_params = { - 'namespace': 'null', - } - - renders.append(FileRender('BackendProcTable.cpp', 'null/ProcTable.cpp', base_backend_params + [null_params])) + renders.append(FileRender('BackendProcTable.cpp', backend + '/ProcTable.' + extension, base_backend_params + [backend_params])) if 'wire' in targets: renders.append(FileRender('wire/WireCmd.h', 'wire/WireCmd_autogen.h', base_backend_params)) diff --git a/src/backend/CMakeLists.txt b/src/backend/CMakeLists.txt index 351697737c..3d9335a8d1 100644 --- a/src/backend/CMakeLists.txt +++ b/src/backend/CMakeLists.txt @@ -13,11 +13,11 @@ # limitations under the License. set(BACKEND_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(D3D12_DIR ${CMAKE_CURRENT_SOURCE_DIR}/d3d12) set(METAL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/metal) set(NULL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/null) set(OPENGL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/opengl) -set(D3D12_DIR ${CMAKE_CURRENT_SOURCE_DIR}/d3d12) -set(TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tests) +set(VULKAN_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vulkan) ################################################################################ # OpenGL Backend @@ -265,6 +265,30 @@ if (NXT_ENABLE_D3D12) ) endif() +################################################################################ +# Vulkan Backend +################################################################################ + +if (NXT_ENABLE_VULKAN) + Generate( + LIB_NAME vulkan_autogen + LIB_TYPE STATIC + FOLDER "backend" + PRINT_NAME "Vulkan backend autogenerated files" + COMMAND_LINE_ARGS + ${GENERATOR_COMMON_ARGS} + -T vulkan + ) + target_link_libraries(vulkan_autogen nxtcpp) + target_include_directories(vulkan_autogen PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_include_directories(vulkan_autogen PUBLIC ${SRC_DIR}) + + list(APPEND BACKEND_SOURCES + ${VULKAN_DIR}/VulkanBackend.cpp + ${VULKAN_DIR}/VulkanBackend.h + ) +endif() + ################################################################################ # Common sources definition of the library ################################################################################ @@ -338,3 +362,6 @@ endif() if (NXT_ENABLE_OPENGL) target_link_libraries(nxt_backend opengl_autogen) endif() +if (NXT_ENABLE_VULKAN) + target_link_libraries(nxt_backend vulkan_autogen) +endif() diff --git a/src/backend/vulkan/GeneratedCodeIncludes.h b/src/backend/vulkan/GeneratedCodeIncludes.h new file mode 100644 index 0000000000..3f454d2d35 --- /dev/null +++ b/src/backend/vulkan/GeneratedCodeIncludes.h @@ -0,0 +1,15 @@ +// 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/vulkan/VulkanBackend.h" diff --git a/src/backend/vulkan/VulkanBackend.cpp b/src/backend/vulkan/VulkanBackend.cpp new file mode 100644 index 0000000000..64fbc5393e --- /dev/null +++ b/src/backend/vulkan/VulkanBackend.cpp @@ -0,0 +1,166 @@ +// 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/vulkan/VulkanBackend.h" + +#include "backend/Commands.h" + +#include + +namespace backend { +namespace vulkan { + + nxtProcTable GetNonValidatingProcs(); + nxtProcTable GetValidatingProcs(); + + void Init(nxtProcTable* procs, nxtDevice* device) { + *procs = GetValidatingProcs(); + *device = reinterpret_cast(new Device); + } + + // Device + + Device::Device() { + } + + Device::~Device() { + } + + BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) { + return new BindGroup(builder); + } + BindGroupLayoutBase* Device::CreateBindGroupLayout(BindGroupLayoutBuilder* builder) { + return new BindGroupLayout(builder); + } + BlendStateBase* Device::CreateBlendState(BlendStateBuilder* builder) { + return new BlendState(builder); + } + BufferBase* Device::CreateBuffer(BufferBuilder* builder) { + return new Buffer(builder); + } + BufferViewBase* Device::CreateBufferView(BufferViewBuilder* builder) { + return new BufferView(builder); + } + CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) { + return new CommandBuffer(builder); + } + ComputePipelineBase* Device::CreateComputePipeline(ComputePipelineBuilder* builder) { + return new ComputePipeline(builder); + } + DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) { + return new DepthStencilState(builder); + } + FramebufferBase* Device::CreateFramebuffer(FramebufferBuilder* builder) { + return new Framebuffer(builder); + } + InputStateBase* Device::CreateInputState(InputStateBuilder* builder) { + return new InputState(builder); + } + PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) { + return new PipelineLayout(builder); + } + QueueBase* Device::CreateQueue(QueueBuilder* builder) { + return new Queue(builder); + } + RenderPassBase* Device::CreateRenderPass(RenderPassBuilder* builder) { + return new RenderPass(builder); + } + RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) { + return new RenderPipeline(builder); + } + SamplerBase* Device::CreateSampler(SamplerBuilder* builder) { + return new Sampler(builder); + } + ShaderModuleBase* Device::CreateShaderModule(ShaderModuleBuilder* builder) { + auto module = new ShaderModule(builder); + + spirv_cross::Compiler compiler(builder->AcquireSpirv()); + module->ExtractSpirvInfo(compiler); + + return module; + } + SwapChainBase* Device::CreateSwapChain(SwapChainBuilder* builder) { + return new SwapChain(builder); + } + TextureBase* Device::CreateTexture(TextureBuilder* builder) { + return new Texture(builder); + } + TextureViewBase* Device::CreateTextureView(TextureViewBuilder* builder) { + return new TextureView(builder); + } + + void Device::TickImpl() { + } + + // Buffer + + Buffer::Buffer(BufferBuilder* builder) + : BufferBase(builder) { + } + + Buffer::~Buffer() { + } + + void Buffer::SetSubDataImpl(uint32_t, uint32_t, const uint32_t*) { + } + + void Buffer::MapReadAsyncImpl(uint32_t, uint32_t, uint32_t) { + } + + void Buffer::UnmapImpl() { + } + + void Buffer::TransitionUsageImpl(nxt::BufferUsageBit, nxt::BufferUsageBit) { + } + + // Queue + + Queue::Queue(QueueBuilder* builder) + : QueueBase(builder) { + } + + Queue::~Queue() { + } + + void Queue::Submit(uint32_t, CommandBuffer* const*) { + } + + // Texture + + Texture::Texture(TextureBuilder* builder) + : TextureBase(builder) { + } + + Texture::~Texture() { + } + + void Texture::TransitionUsageImpl(nxt::TextureUsageBit, nxt::TextureUsageBit) { + } + + // SwapChain + + SwapChain::SwapChain(SwapChainBuilder* builder) + : SwapChainBase(builder) { + const auto& im = GetImplementation(); + im.Init(im.userData, nullptr); + } + + SwapChain::~SwapChain() { + } + + TextureBase* SwapChain::GetNextTextureImpl(TextureBuilder* builder) { + return GetDevice()->CreateTexture(builder); + } +} +} diff --git a/src/backend/vulkan/VulkanBackend.h b/src/backend/vulkan/VulkanBackend.h new file mode 100644 index 0000000000..bf2b488a12 --- /dev/null +++ b/src/backend/vulkan/VulkanBackend.h @@ -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. + +#ifndef BACKEND_VULKAN_VULKANBACKEND_H_ +#define BACKEND_VULKAN_VULKANBACKEND_H_ + +#include "nxt/nxtcpp.h" + +#include "backend/Buffer.h" +#include "backend/BindGroup.h" +#include "backend/BindGroupLayout.h" +#include "backend/BlendState.h" +#include "backend/Device.h" +#include "backend/CommandBuffer.h" +#include "backend/ComputePipeline.h" +#include "backend/DepthStencilState.h" +#include "backend/Framebuffer.h" +#include "backend/InputState.h" +#include "backend/PipelineLayout.h" +#include "backend/Queue.h" +#include "backend/RenderPass.h" +#include "backend/RenderPipeline.h" +#include "backend/Sampler.h" +#include "backend/ShaderModule.h" +#include "backend/SwapChain.h" +#include "backend/Texture.h" +#include "backend/ToBackend.h" + +namespace backend { +namespace vulkan { + + using BindGroup = BindGroupBase; + using BindGroupLayout = BindGroupLayoutBase; + using BlendState = BlendStateBase; + class Buffer; + using BufferView = BufferViewBase; + using CommandBuffer = CommandBufferBase; + using ComputePipeline = ComputePipelineBase; + using DepthStencilState = DepthStencilStateBase; + class Device; + using Framebuffer = FramebufferBase; + using InputState = InputStateBase; + using PipelineLayout = PipelineLayoutBase; + class Queue; + using RenderPass = RenderPassBase; + using RenderPipeline = RenderPipelineBase; + using Sampler = SamplerBase; + using ShaderModule = ShaderModuleBase; + class SwapChain; + class Texture; + using TextureView = TextureViewBase; + + struct VulkanBackendTraits { + using BindGroupType = BindGroup; + using BindGroupLayoutType = BindGroupLayout; + using BlendStateType = BlendState; + 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 PipelineLayoutType = PipelineLayout; + using QueueType = Queue; + using RenderPassType = RenderPass; + using RenderPipelineType = RenderPipeline; + using SamplerType = Sampler; + using ShaderModuleType = ShaderModule; + using SwapChainType = SwapChain; + using TextureType = Texture; + using TextureViewType = TextureView; + }; + + template + auto ToBackend(T&& common) -> decltype(ToBackendBase(common)) { + return ToBackendBase(common); + } + + class Device : public DeviceBase { + public: + Device(); + ~Device(); + + BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override; + BindGroupLayoutBase* CreateBindGroupLayout(BindGroupLayoutBuilder* builder) override; + BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override; + 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; + FramebufferBase* CreateFramebuffer(FramebufferBuilder* 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; + SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override; + TextureBase* CreateTexture(TextureBuilder* builder) override; + TextureViewBase* CreateTextureView(TextureViewBuilder* builder) override; + + void TickImpl() override; + }; + + class Buffer : public BufferBase { + public: + Buffer(BufferBuilder* builder); + ~Buffer(); + + private: + void SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) override; + void MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) override; + void UnmapImpl() override; + void TransitionUsageImpl(nxt::BufferUsageBit currentUsage, nxt::BufferUsageBit targetUsage) override; + }; + + class Queue : public QueueBase { + public: + Queue(QueueBuilder* builder); + ~Queue(); + + // NXT API + void Submit(uint32_t numCommands, CommandBuffer* const * commands); + }; + + class Texture : public TextureBase { + public: + Texture(TextureBuilder* builder); + ~Texture(); + + private: + void TransitionUsageImpl(nxt::TextureUsageBit currentUsage, nxt::TextureUsageBit targetUsage) override; + }; + + class SwapChain : public SwapChainBase { + public: + SwapChain(SwapChainBuilder* builder); + ~SwapChain(); + + protected: + TextureBase* GetNextTextureImpl(TextureBuilder* builder) override; + }; + +} +} + +#endif // BACKEND_VULKAN_VULKANBACKEND_H_ diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index 1d273ff400..6ee868e717 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -48,6 +48,12 @@ if (NXT_ENABLE_OPENGL) ) endif() +if (NXT_ENABLE_VULKAN) + list(APPEND UTILS_SOURCES + ${UTILS_DIR}/VulkanBinding.cpp + ) +endif() + add_library(utils STATIC ${UTILS_SOURCES}) target_link_libraries(utils nxt_backend shaderc nxtcpp nxt) target_include_directories(utils PUBLIC ${SRC_DIR}) diff --git a/src/utils/VulkanBinding.cpp b/src/utils/VulkanBinding.cpp new file mode 100644 index 0000000000..869ac2c020 --- /dev/null +++ b/src/utils/VulkanBinding.cpp @@ -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. + +#include "utils/BackendBinding.h" + +namespace backend { + namespace vulkan { + void Init(nxtProcTable* procs, nxtDevice* device); + } +} + +namespace utils { + + class VulkanBinding : public BackendBinding { + public: + void SetupGLFWWindowHints() override { + } + void GetProcAndDevice(nxtProcTable* procs, nxtDevice* device) override { + backend::vulkan::Init(procs, device); + } + uint64_t GetSwapChainImplementation() override { + return 0; + } + }; + + + BackendBinding* CreateVulkanBinding() { + return new VulkanBinding; + } + +}