Vulkan: Implement BindGroupLayout

This commit is contained in:
Corentin Wallez 2018-02-02 13:06:58 -05:00 committed by Corentin Wallez
parent 8df4142870
commit e7362d0b1b
9 changed files with 176 additions and 8 deletions

View File

@ -92,6 +92,10 @@ namespace backend {
return mBindingInfo; return mBindingInfo;
} }
DeviceBase* BindGroupLayoutBase::GetDevice() const {
return mDevice;
}
// BindGroupLayoutBuilder // BindGroupLayoutBuilder
BindGroupLayoutBuilder::BindGroupLayoutBuilder(DeviceBase* device) : Builder(device) { BindGroupLayoutBuilder::BindGroupLayoutBuilder(DeviceBase* device) : Builder(device) {

View File

@ -39,6 +39,8 @@ namespace backend {
}; };
const LayoutBindingInfo& GetBindingInfo() const; const LayoutBindingInfo& GetBindingInfo() const;
DeviceBase* GetDevice() const;
private: private:
DeviceBase* mDevice; DeviceBase* mDevice;
LayoutBindingInfo mBindingInfo; LayoutBindingInfo mBindingInfo;

View File

@ -288,6 +288,8 @@ if (NXT_ENABLE_VULKAN)
target_include_directories(vulkan_autogen PUBLIC ${SRC_DIR}) target_include_directories(vulkan_autogen PUBLIC ${SRC_DIR})
list(APPEND BACKEND_SOURCES list(APPEND BACKEND_SOURCES
${VULKAN_DIR}/BindGroupLayoutVk.cpp
${VULKAN_DIR}/BindGroupLayoutVk.h
${VULKAN_DIR}/BlendStateVk.cpp ${VULKAN_DIR}/BlendStateVk.cpp
${VULKAN_DIR}/BlendStateVk.h ${VULKAN_DIR}/BlendStateVk.h
${VULKAN_DIR}/BufferUploader.cpp ${VULKAN_DIR}/BufferUploader.cpp

View File

@ -0,0 +1,104 @@
// Copyright 2018 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/BindGroupLayoutVk.h"
#include "backend/vulkan/VulkanBackend.h"
namespace backend { namespace vulkan {
namespace {
VkDescriptorType VulkanDescriptorType(nxt::BindingType type) {
switch (type) {
case nxt::BindingType::UniformBuffer:
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
case nxt::BindingType::Sampler:
return VK_DESCRIPTOR_TYPE_SAMPLER;
case nxt::BindingType::SampledTexture:
return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
case nxt::BindingType::StorageBuffer:
return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
default:
UNREACHABLE();
}
}
VkShaderStageFlags VulkanShaderStageFlags(nxt::ShaderStageBit stages) {
VkShaderStageFlags flags = 0;
if (stages & nxt::ShaderStageBit::Vertex) {
flags |= VK_SHADER_STAGE_VERTEX_BIT;
}
if (stages & nxt::ShaderStageBit::Fragment) {
flags |= VK_SHADER_STAGE_FRAGMENT_BIT;
}
if (stages & nxt::ShaderStageBit::Compute) {
flags |= VK_SHADER_STAGE_COMPUTE_BIT;
}
return flags;
}
} // anonymous namespace
BindGroupLayout::BindGroupLayout(BindGroupLayoutBuilder* builder)
: BindGroupLayoutBase(builder) {
const auto& info = GetBindingInfo();
// Compute the bindings that will be chained in the DescriptorSetLayout create info. We add
// one entry per binding set. This might be optimized by computing continuous ranges of
// bindings of the same type.
uint32_t numBindings = 0;
std::array<VkDescriptorSetLayoutBinding, kMaxBindingsPerGroup> bindings;
for (uint32_t bindingIndex : IterateBitSet(info.mask)) {
auto& binding = bindings[numBindings];
binding.binding = bindingIndex;
binding.descriptorType = VulkanDescriptorType(info.types[bindingIndex]);
binding.descriptorCount = 1;
binding.stageFlags = VulkanShaderStageFlags(info.visibilities[bindingIndex]);
binding.pImmutableSamplers = nullptr;
numBindings++;
}
VkDescriptorSetLayoutCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.bindingCount = numBindings;
createInfo.pBindings = bindings.data();
Device* device = ToBackend(GetDevice());
if (device->fn.CreateDescriptorSetLayout(device->GetVkDevice(), &createInfo, nullptr,
&mHandle) != VK_SUCCESS) {
ASSERT(false);
}
}
BindGroupLayout::~BindGroupLayout() {
// DescriptorSetLayout aren't used by execution on the GPU and can be deleted at any time,
// so we destroy mHandle immediately instead of using the FencedDeleter
if (mHandle != VK_NULL_HANDLE) {
Device* device = ToBackend(GetDevice());
device->fn.DestroyDescriptorSetLayout(device->GetVkDevice(), mHandle, nullptr);
mHandle = VK_NULL_HANDLE;
}
}
VkDescriptorSetLayout BindGroupLayout::GetHandle() const {
return mHandle;
}
}} // namespace backend::vulkan

View File

@ -0,0 +1,39 @@
// Copyright 2018 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_BINDGROUPLAYOUTVK_H_
#define BACKEND_VULKAN_BINDGROUPLAYOUTVK_H_
#include "backend/BindGroupLayout.h"
#include "common/vulkan_platform.h"
namespace backend { namespace vulkan {
class Device;
class BindGroupLayout : public BindGroupLayoutBase {
public:
BindGroupLayout(BindGroupLayoutBuilder* builder);
~BindGroupLayout();
VkDescriptorSetLayout GetHandle() const;
private:
VkDescriptorSetLayout mHandle = VK_NULL_HANDLE;
};
}} // namespace backend::vulkan
#endif // BACKEND_VULKAN_BINDGROUPLAYOUTVK_H_

View File

@ -12,6 +12,7 @@
// 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.
#include "backend/vulkan/BindGroupLayoutVk.h"
#include "backend/vulkan/BlendStateVk.h" #include "backend/vulkan/BlendStateVk.h"
#include "backend/vulkan/BufferVk.h" #include "backend/vulkan/BufferVk.h"
#include "backend/vulkan/CommandBufferVk.h" #include "backend/vulkan/CommandBufferVk.h"

View File

@ -14,6 +14,7 @@
#include "backend/vulkan/PipelineLayoutVk.h" #include "backend/vulkan/PipelineLayoutVk.h"
#include "backend/vulkan/BindGroupLayoutVk.h"
#include "backend/vulkan/FencedDeleter.h" #include "backend/vulkan/FencedDeleter.h"
#include "backend/vulkan/VulkanBackend.h" #include "backend/vulkan/VulkanBackend.h"
@ -21,16 +22,31 @@ namespace backend { namespace vulkan {
PipelineLayout::PipelineLayout(PipelineLayoutBuilder* builder) PipelineLayout::PipelineLayout(PipelineLayoutBuilder* builder)
: PipelineLayoutBase(builder), mDevice(ToBackend(builder->GetDevice())) { : PipelineLayoutBase(builder), mDevice(ToBackend(builder->GetDevice())) {
// Create an empty pipeline layout for now // Compute the array of VkDescriptorSetLayouts that will be chained in the create info.
// TODO(cwallez@chromium.org): Add support for descriptor sets, figure out push constants // TODO(cwallez@chromium.org) Vulkan doesn't allow holes in this array, should we expose
// this constraints at the NXT level?
uint32_t numSetLayouts = 0;
std::array<VkDescriptorSetLayout, kMaxBindGroups> setLayouts;
for (uint32_t setIndex : IterateBitSet(GetBindGroupsLayoutMask())) {
setLayouts[numSetLayouts] = ToBackend(GetBindGroupLayout(setIndex))->GetHandle();
numSetLayouts++;
}
// Specify NXT's push constant range on all pipeline layouts because we don't know which
// pipelines might use it.
VkPushConstantRange pushConstantRange;
pushConstantRange.stageFlags = VK_SHADER_STAGE_ALL;
pushConstantRange.offset = 0;
pushConstantRange.size = 4 * kMaxPushConstants;
VkPipelineLayoutCreateInfo createInfo; VkPipelineLayoutCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
createInfo.pNext = nullptr; createInfo.pNext = nullptr;
createInfo.flags = 0; createInfo.flags = 0;
createInfo.setLayoutCount = 0; createInfo.setLayoutCount = numSetLayouts;
createInfo.pSetLayouts = nullptr; createInfo.pSetLayouts = setLayouts.data();
createInfo.pushConstantRangeCount = 0; createInfo.pushConstantRangeCount = 1;
createInfo.pPushConstantRanges = nullptr; createInfo.pPushConstantRanges = &pushConstantRange;
if (mDevice->fn.CreatePipelineLayout(mDevice->GetVkDevice(), &createInfo, nullptr, if (mDevice->fn.CreatePipelineLayout(mDevice->GetVkDevice(), &createInfo, nullptr,
&mHandle) != VK_SUCCESS) { &mHandle) != VK_SUCCESS) {

View File

@ -15,6 +15,7 @@
#include "backend/vulkan/VulkanBackend.h" #include "backend/vulkan/VulkanBackend.h"
#include "backend/Commands.h" #include "backend/Commands.h"
#include "backend/vulkan/BindGroupLayoutVk.h"
#include "backend/vulkan/BlendStateVk.h" #include "backend/vulkan/BlendStateVk.h"
#include "backend/vulkan/BufferUploader.h" #include "backend/vulkan/BufferUploader.h"
#include "backend/vulkan/BufferVk.h" #include "backend/vulkan/BufferVk.h"

View File

@ -18,7 +18,6 @@
#include "nxt/nxtcpp.h" #include "nxt/nxtcpp.h"
#include "backend/BindGroup.h" #include "backend/BindGroup.h"
#include "backend/BindGroupLayout.h"
#include "backend/ComputePipeline.h" #include "backend/ComputePipeline.h"
#include "backend/DepthStencilState.h" #include "backend/DepthStencilState.h"
#include "backend/Device.h" #include "backend/Device.h"
@ -36,7 +35,7 @@
namespace backend { namespace vulkan { namespace backend { namespace vulkan {
using BindGroup = BindGroupBase; using BindGroup = BindGroupBase;
using BindGroupLayout = BindGroupLayoutBase; class BindGroupLayout;
class BlendState; class BlendState;
class Buffer; class Buffer;
using BufferView = BufferViewBase; using BufferView = BufferViewBase;