Vulkan: Implement RenderPipeline
This commit is contained in:
parent
eb135f6fc0
commit
2b391dac74
|
@ -307,6 +307,10 @@ if (NXT_ENABLE_VULKAN)
|
|||
${VULKAN_DIR}/PipelineLayoutVk.h
|
||||
${VULKAN_DIR}/RenderPassVk.cpp
|
||||
${VULKAN_DIR}/RenderPassVk.h
|
||||
${VULKAN_DIR}/RenderPipelineVk.cpp
|
||||
${VULKAN_DIR}/RenderPipelineVk.h
|
||||
${VULKAN_DIR}/ShaderModuleVk.cpp
|
||||
${VULKAN_DIR}/ShaderModuleVk.h
|
||||
${VULKAN_DIR}/TextureVk.cpp
|
||||
${VULKAN_DIR}/TextureVk.h
|
||||
${VULKAN_DIR}/VulkanBackend.cpp
|
||||
|
|
|
@ -15,7 +15,11 @@
|
|||
#ifndef BACKEND_RENDERPIPELINE_H_
|
||||
#define BACKEND_RENDERPIPELINE_H_
|
||||
|
||||
#include "backend/BlendState.h"
|
||||
#include "backend/DepthStencilState.h"
|
||||
#include "backend/InputState.h"
|
||||
#include "backend/Pipeline.h"
|
||||
#include "backend/RenderPass.h"
|
||||
|
||||
#include "nxt/nxtcpp.h"
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "backend/vulkan/BufferVk.h"
|
||||
#include "backend/vulkan/FramebufferVk.h"
|
||||
#include "backend/vulkan/RenderPassVk.h"
|
||||
#include "backend/vulkan/RenderPipelineVk.h"
|
||||
#include "backend/vulkan/TextureVk.h"
|
||||
#include "backend/vulkan/VulkanBackend.h"
|
||||
|
||||
|
@ -69,7 +70,6 @@ namespace backend { namespace vulkan {
|
|||
Command type;
|
||||
while (mCommands.NextCommandId(&type)) {
|
||||
switch (type) {
|
||||
|
||||
case Command::CopyBufferToBuffer: {
|
||||
CopyBufferToBufferCmd* copy = mCommands.NextCommand<CopyBufferToBufferCmd>();
|
||||
auto& src = copy->source;
|
||||
|
@ -140,8 +140,40 @@ namespace backend { namespace vulkan {
|
|||
beginInfo.clearValueCount = renderPass->GetAttachmentCount();
|
||||
beginInfo.pClearValues = clearValues.data();
|
||||
|
||||
|
||||
device->fn.CmdBeginRenderPass(commands, &beginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
// Set all the dynamic state just in case.
|
||||
device->fn.CmdSetLineWidth(commands, 1.0f);
|
||||
device->fn.CmdSetDepthBounds(commands, 0.0f, 1.0f);
|
||||
|
||||
float blendConstants[4] = {
|
||||
1.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
};
|
||||
device->fn.CmdSetBlendConstants(commands, blendConstants);
|
||||
|
||||
device->fn.CmdSetStencilCompareMask(commands, VK_STENCIL_FRONT_AND_BACK, 0);
|
||||
device->fn.CmdSetStencilWriteMask(commands, VK_STENCIL_FRONT_AND_BACK, 0);
|
||||
device->fn.CmdSetStencilReference(commands, VK_STENCIL_FRONT_AND_BACK, 0);
|
||||
|
||||
// The viewport and scissor default to cover all of the attachments
|
||||
VkViewport viewport;
|
||||
viewport.x = 0.0f;
|
||||
viewport.y = 0.0f;
|
||||
viewport.width = static_cast<float>(framebuffer->GetWidth());
|
||||
viewport.height = static_cast<float>(framebuffer->GetHeight());
|
||||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
device->fn.CmdSetViewport(commands, 0, 1, &viewport);
|
||||
|
||||
VkRect2D scissorRect;
|
||||
scissorRect.offset.x = 0;
|
||||
scissorRect.offset.y = 0;
|
||||
scissorRect.extent.width = framebuffer->GetWidth();
|
||||
scissorRect.extent.height = framebuffer->GetHeight();
|
||||
device->fn.CmdSetScissor(commands, 0, 1, &scissorRect);
|
||||
} break;
|
||||
|
||||
case Command::BeginRenderSubpass: {
|
||||
|
@ -185,6 +217,14 @@ namespace backend { namespace vulkan {
|
|||
VK_INDEX_TYPE_UINT16);
|
||||
} break;
|
||||
|
||||
case Command::SetRenderPipeline: {
|
||||
SetRenderPipelineCmd* cmd = mCommands.NextCommand<SetRenderPipelineCmd>();
|
||||
RenderPipeline* pipeline = ToBackend(cmd->pipeline).Get();
|
||||
|
||||
device->fn.CmdBindPipeline(commands, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pipeline->GetHandle());
|
||||
} break;
|
||||
|
||||
case Command::SetVertexBuffers: {
|
||||
SetVertexBuffersCmd* cmd = mCommands.NextCommand<SetVertexBuffersCmd>();
|
||||
auto buffers = mCommands.NextData<Ref<BufferBase>>(cmd->count);
|
||||
|
|
|
@ -27,8 +27,10 @@ namespace backend { namespace vulkan {
|
|||
ASSERT(mImagesToDelete.Empty());
|
||||
ASSERT(mImageViewsToDelete.Empty());
|
||||
ASSERT(mMemoriesToDelete.Empty());
|
||||
ASSERT(mPipelinesToDelete.Empty());
|
||||
ASSERT(mPipelineLayoutsToDelete.Empty());
|
||||
ASSERT(mRenderPassesToDelete.Empty());
|
||||
ASSERT(mShaderModulesToDelete.Empty());
|
||||
}
|
||||
|
||||
void FencedDeleter::DeleteWhenUnused(VkBuffer buffer) {
|
||||
|
@ -51,6 +53,10 @@ namespace backend { namespace vulkan {
|
|||
mImageViewsToDelete.Enqueue(view, mDevice->GetSerial());
|
||||
}
|
||||
|
||||
void FencedDeleter::DeleteWhenUnused(VkPipeline pipeline) {
|
||||
mPipelinesToDelete.Enqueue(pipeline, mDevice->GetSerial());
|
||||
}
|
||||
|
||||
void FencedDeleter::DeleteWhenUnused(VkPipelineLayout layout) {
|
||||
mPipelineLayoutsToDelete.Enqueue(layout, mDevice->GetSerial());
|
||||
}
|
||||
|
@ -59,6 +65,10 @@ namespace backend { namespace vulkan {
|
|||
mRenderPassesToDelete.Enqueue(renderPass, mDevice->GetSerial());
|
||||
}
|
||||
|
||||
void FencedDeleter::DeleteWhenUnused(VkShaderModule module) {
|
||||
mShaderModulesToDelete.Enqueue(module, mDevice->GetSerial());
|
||||
}
|
||||
|
||||
void FencedDeleter::Tick(Serial completedSerial) {
|
||||
VkDevice vkDevice = mDevice->GetVkDevice();
|
||||
|
||||
|
@ -98,6 +108,15 @@ namespace backend { namespace vulkan {
|
|||
}
|
||||
mImageViewsToDelete.ClearUpTo(completedSerial);
|
||||
|
||||
for (VkShaderModule module : mShaderModulesToDelete.IterateUpTo(completedSerial)) {
|
||||
mDevice->fn.DestroyShaderModule(vkDevice, module, nullptr);
|
||||
}
|
||||
mShaderModulesToDelete.ClearUpTo(completedSerial);
|
||||
|
||||
for (VkPipeline pipeline : mPipelinesToDelete.IterateUpTo(completedSerial)) {
|
||||
mDevice->fn.DestroyPipeline(vkDevice, pipeline, nullptr);
|
||||
}
|
||||
mPipelinesToDelete.ClearUpTo(completedSerial);
|
||||
}
|
||||
|
||||
}} // namespace backend::vulkan
|
||||
|
|
|
@ -34,6 +34,8 @@ namespace backend { namespace vulkan {
|
|||
void DeleteWhenUnused(VkImageView view);
|
||||
void DeleteWhenUnused(VkPipelineLayout layout);
|
||||
void DeleteWhenUnused(VkRenderPass renderPass);
|
||||
void DeleteWhenUnused(VkPipeline pipeline);
|
||||
void DeleteWhenUnused(VkShaderModule module);
|
||||
|
||||
void Tick(Serial completedSerial);
|
||||
|
||||
|
@ -44,8 +46,10 @@ namespace backend { namespace vulkan {
|
|||
SerialQueue<VkDeviceMemory> mMemoriesToDelete;
|
||||
SerialQueue<VkImage> mImagesToDelete;
|
||||
SerialQueue<VkImageView> mImageViewsToDelete;
|
||||
SerialQueue<VkPipeline> mPipelinesToDelete;
|
||||
SerialQueue<VkPipelineLayout> mPipelineLayoutsToDelete;
|
||||
SerialQueue<VkRenderPass> mRenderPassesToDelete;
|
||||
SerialQueue<VkShaderModule> mShaderModulesToDelete;
|
||||
};
|
||||
|
||||
}} // namespace backend::vulkan
|
||||
|
|
|
@ -18,5 +18,7 @@
|
|||
#include "backend/vulkan/InputStateVk.h"
|
||||
#include "backend/vulkan/PipelineLayoutVk.h"
|
||||
#include "backend/vulkan/RenderPassVk.h"
|
||||
#include "backend/vulkan/RenderPipelineVk.h"
|
||||
#include "backend/vulkan/ShaderModuleVk.h"
|
||||
#include "backend/vulkan/TextureVk.h"
|
||||
#include "backend/vulkan/VulkanBackend.h"
|
||||
|
|
|
@ -0,0 +1,244 @@
|
|||
// 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/RenderPipelineVk.h"
|
||||
|
||||
#include "backend/vulkan/FencedDeleter.h"
|
||||
#include "backend/vulkan/InputStateVk.h"
|
||||
#include "backend/vulkan/PipelineLayoutVk.h"
|
||||
#include "backend/vulkan/RenderPassVk.h"
|
||||
#include "backend/vulkan/ShaderModuleVk.h"
|
||||
#include "backend/vulkan/VulkanBackend.h"
|
||||
|
||||
namespace backend { namespace vulkan {
|
||||
|
||||
namespace {
|
||||
|
||||
VkPrimitiveTopology VulkanPrimitiveTopology(nxt::PrimitiveTopology topology) {
|
||||
switch (topology) {
|
||||
case nxt::PrimitiveTopology::PointList:
|
||||
return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
||||
case nxt::PrimitiveTopology::LineList:
|
||||
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
|
||||
case nxt::PrimitiveTopology::LineStrip:
|
||||
return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
|
||||
case nxt::PrimitiveTopology::TriangleList:
|
||||
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
case nxt::PrimitiveTopology::TriangleStrip:
|
||||
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder)
|
||||
: RenderPipelineBase(builder), mDevice(ToBackend(builder->GetDevice())) {
|
||||
// Eventually a bunch of the structures that need to be chained in the create info will be
|
||||
// held by objects such as the BlendState. They aren't implemented yet so we initialize
|
||||
// everything here.
|
||||
|
||||
VkPipelineShaderStageCreateInfo shaderStages[2];
|
||||
{
|
||||
const auto& vertexStageInfo = builder->GetStageInfo(nxt::ShaderStage::Vertex);
|
||||
const auto& fragmentStageInfo = builder->GetStageInfo(nxt::ShaderStage::Fragment);
|
||||
|
||||
shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
shaderStages[0].pNext = nullptr;
|
||||
shaderStages[0].flags = 0;
|
||||
shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
shaderStages[0].module = ToBackend(vertexStageInfo.module)->GetHandle();
|
||||
shaderStages[0].pName = vertexStageInfo.entryPoint.c_str();
|
||||
shaderStages[0].pSpecializationInfo = nullptr;
|
||||
|
||||
shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
shaderStages[1].pNext = nullptr;
|
||||
shaderStages[1].flags = 0;
|
||||
shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
shaderStages[1].module = ToBackend(fragmentStageInfo.module)->GetHandle();
|
||||
shaderStages[1].pName = fragmentStageInfo.entryPoint.c_str();
|
||||
shaderStages[1].pSpecializationInfo = nullptr;
|
||||
}
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssembly;
|
||||
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
inputAssembly.pNext = nullptr;
|
||||
inputAssembly.flags = 0;
|
||||
inputAssembly.topology = VulkanPrimitiveTopology(GetPrimitiveTopology());
|
||||
// Primitive restart is always enabled in NXT (because of Metal)
|
||||
inputAssembly.primitiveRestartEnable = VK_TRUE;
|
||||
|
||||
// A dummy viewport/scissor info. The validation layers force use to provide at least one
|
||||
// scissor and one viewport here, even if we choose to make them dynamic.
|
||||
VkViewport viewportDesc;
|
||||
viewportDesc.x = 0.0f;
|
||||
viewportDesc.y = 0.0f;
|
||||
viewportDesc.width = 1.0f;
|
||||
viewportDesc.height = 1.0f;
|
||||
viewportDesc.minDepth = 0.0f;
|
||||
viewportDesc.maxDepth = 1.0f;
|
||||
VkRect2D scissorRect;
|
||||
scissorRect.offset.x = 0;
|
||||
scissorRect.offset.y = 0;
|
||||
scissorRect.extent.width = 1;
|
||||
scissorRect.extent.height = 1;
|
||||
VkPipelineViewportStateCreateInfo viewport;
|
||||
viewport.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||
viewport.pNext = nullptr;
|
||||
viewport.flags = 0;
|
||||
viewport.viewportCount = 1;
|
||||
viewport.pViewports = &viewportDesc;
|
||||
viewport.scissorCount = 1;
|
||||
viewport.pScissors = &scissorRect;
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rasterization;
|
||||
rasterization.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||
rasterization.pNext = nullptr;
|
||||
rasterization.flags = 0;
|
||||
rasterization.depthClampEnable = VK_FALSE;
|
||||
rasterization.rasterizerDiscardEnable = VK_FALSE;
|
||||
rasterization.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
rasterization.cullMode = VK_CULL_MODE_NONE;
|
||||
rasterization.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
rasterization.depthBiasEnable = VK_FALSE;
|
||||
rasterization.depthBiasConstantFactor = 0.0f;
|
||||
rasterization.depthBiasClamp = 0.0f;
|
||||
rasterization.depthBiasSlopeFactor = 0.0f;
|
||||
rasterization.lineWidth = 1.0f;
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo multisample;
|
||||
multisample.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||
multisample.pNext = nullptr;
|
||||
multisample.flags = 0;
|
||||
multisample.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
multisample.sampleShadingEnable = VK_FALSE;
|
||||
multisample.minSampleShading = 0.0f;
|
||||
multisample.pSampleMask = nullptr;
|
||||
multisample.alphaToCoverageEnable = VK_FALSE;
|
||||
multisample.alphaToOneEnable = VK_FALSE;
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencil;
|
||||
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||
depthStencil.pNext = nullptr;
|
||||
depthStencil.flags = 0;
|
||||
depthStencil.depthTestEnable = VK_TRUE;
|
||||
depthStencil.depthWriteEnable = VK_TRUE;
|
||||
depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
|
||||
depthStencil.depthBoundsTestEnable = VK_FALSE;
|
||||
depthStencil.stencilTestEnable = VK_FALSE;
|
||||
depthStencil.front.failOp = VK_STENCIL_OP_KEEP;
|
||||
depthStencil.front.passOp = VK_STENCIL_OP_KEEP;
|
||||
depthStencil.front.depthFailOp = VK_STENCIL_OP_KEEP;
|
||||
depthStencil.front.compareOp = VK_COMPARE_OP_NEVER;
|
||||
depthStencil.front.compareMask = 0;
|
||||
depthStencil.front.writeMask = 0;
|
||||
depthStencil.front.reference = 0;
|
||||
depthStencil.back.failOp = VK_STENCIL_OP_KEEP;
|
||||
depthStencil.back.passOp = VK_STENCIL_OP_KEEP;
|
||||
depthStencil.back.depthFailOp = VK_STENCIL_OP_KEEP;
|
||||
depthStencil.back.compareOp = VK_COMPARE_OP_NEVER;
|
||||
depthStencil.back.compareMask = 0;
|
||||
depthStencil.back.writeMask = 0;
|
||||
depthStencil.back.reference = 0;
|
||||
depthStencil.minDepthBounds = 0.0f;
|
||||
depthStencil.maxDepthBounds = 0.0f;
|
||||
|
||||
// Even when not using independent blend, we need to provide blend information for every
|
||||
// single attachment.
|
||||
std::array<VkPipelineColorBlendAttachmentState, kMaxColorAttachments> colorBlendAttachments;
|
||||
for (auto& attachment : colorBlendAttachments) {
|
||||
attachment.blendEnable = VK_FALSE;
|
||||
attachment.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
attachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
attachment.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
attachment.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
attachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
|
||||
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
}
|
||||
VkPipelineColorBlendStateCreateInfo colorBlend;
|
||||
colorBlend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||
colorBlend.pNext = nullptr;
|
||||
colorBlend.flags = 0;
|
||||
colorBlend.logicOpEnable = VK_FALSE;
|
||||
colorBlend.logicOp = VK_LOGIC_OP_CLEAR;
|
||||
colorBlend.attachmentCount = kMaxColorAttachments;
|
||||
colorBlend.pAttachments = colorBlendAttachments.data();
|
||||
colorBlend.blendConstants[0] = 0.0f;
|
||||
colorBlend.blendConstants[1] = 0.0f;
|
||||
colorBlend.blendConstants[2] = 0.0f;
|
||||
colorBlend.blendConstants[3] = 0.0f;
|
||||
|
||||
// Tag all state as dynamic.
|
||||
VkDynamicState dynamicStates[] = {
|
||||
VK_DYNAMIC_STATE_VIEWPORT,
|
||||
VK_DYNAMIC_STATE_SCISSOR,
|
||||
VK_DYNAMIC_STATE_LINE_WIDTH,
|
||||
VK_DYNAMIC_STATE_DEPTH_BIAS,
|
||||
VK_DYNAMIC_STATE_BLEND_CONSTANTS,
|
||||
VK_DYNAMIC_STATE_DEPTH_BOUNDS,
|
||||
VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
|
||||
VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
|
||||
VK_DYNAMIC_STATE_STENCIL_REFERENCE,
|
||||
};
|
||||
VkPipelineDynamicStateCreateInfo dynamic;
|
||||
dynamic.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
||||
dynamic.pNext = nullptr;
|
||||
dynamic.flags = 0;
|
||||
dynamic.dynamicStateCount = sizeof(dynamicStates) / sizeof(dynamicStates[0]);
|
||||
dynamic.pDynamicStates = dynamicStates;
|
||||
|
||||
// The create info chains in a bunch of things created on the stack here or inside state
|
||||
// objects.
|
||||
VkGraphicsPipelineCreateInfo createInfo;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
createInfo.pNext = nullptr;
|
||||
createInfo.flags = 0;
|
||||
createInfo.stageCount = 2;
|
||||
createInfo.pStages = shaderStages;
|
||||
createInfo.pVertexInputState = ToBackend(GetInputState())->GetCreateInfo();
|
||||
createInfo.pInputAssemblyState = &inputAssembly;
|
||||
createInfo.pTessellationState = nullptr;
|
||||
createInfo.pViewportState = &viewport;
|
||||
createInfo.pRasterizationState = &rasterization;
|
||||
createInfo.pMultisampleState = &multisample;
|
||||
createInfo.pDepthStencilState = &depthStencil;
|
||||
createInfo.pColorBlendState = &colorBlend;
|
||||
createInfo.pDynamicState = &dynamic;
|
||||
createInfo.layout = ToBackend(GetLayout())->GetHandle();
|
||||
createInfo.renderPass = ToBackend(GetRenderPass())->GetHandle();
|
||||
createInfo.subpass = GetSubPass();
|
||||
createInfo.basePipelineHandle = VK_NULL_HANDLE;
|
||||
createInfo.basePipelineIndex = -1;
|
||||
|
||||
if (mDevice->fn.CreateGraphicsPipelines(mDevice->GetVkDevice(), VK_NULL_HANDLE, 1,
|
||||
&createInfo, nullptr, &mHandle) != VK_SUCCESS) {
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
RenderPipeline::~RenderPipeline() {
|
||||
if (mHandle != VK_NULL_HANDLE) {
|
||||
mDevice->GetFencedDeleter()->DeleteWhenUnused(mHandle);
|
||||
mHandle = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
VkPipeline RenderPipeline::GetHandle() const {
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
}} // namespace backend::vulkan
|
|
@ -0,0 +1,40 @@
|
|||
// 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_RENDERPIPELINEVK_H_
|
||||
#define BACKEND_VULKAN_RENDERPIPELINEVK_H_
|
||||
|
||||
#include "backend/RenderPipeline.h"
|
||||
|
||||
#include "backend/vulkan/vulkan_platform.h"
|
||||
|
||||
namespace backend { namespace vulkan {
|
||||
|
||||
class Device;
|
||||
|
||||
class RenderPipeline : public RenderPipelineBase {
|
||||
public:
|
||||
RenderPipeline(RenderPipelineBuilder* builder);
|
||||
~RenderPipeline();
|
||||
|
||||
VkPipeline GetHandle() const;
|
||||
|
||||
private:
|
||||
VkPipeline mHandle = VK_NULL_HANDLE;
|
||||
Device* mDevice = nullptr;
|
||||
};
|
||||
|
||||
}} // namespace backend::vulkan
|
||||
|
||||
#endif // BACKEND_VULKAN_RENDERPIPELINEVK_H_
|
|
@ -0,0 +1,60 @@
|
|||
// 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/ShaderModuleVk.h"
|
||||
|
||||
#include "backend/vulkan/FencedDeleter.h"
|
||||
#include "backend/vulkan/VulkanBackend.h"
|
||||
|
||||
#include <spirv-cross/spirv_cross.hpp>
|
||||
|
||||
namespace backend { namespace vulkan {
|
||||
|
||||
ShaderModule::ShaderModule(ShaderModuleBuilder* builder) : ShaderModuleBase(builder) {
|
||||
std::vector<uint32_t> spirv = builder->AcquireSpirv();
|
||||
|
||||
// Use SPIRV-Cross to extract info from the SPIRV even if Vulkan consumes SPIRV. We want to
|
||||
// have a translation step eventually anyway.
|
||||
spirv_cross::Compiler compiler(spirv);
|
||||
ExtractSpirvInfo(compiler);
|
||||
|
||||
VkShaderModuleCreateInfo createInfo;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
createInfo.pNext = nullptr;
|
||||
createInfo.flags = 0;
|
||||
createInfo.codeSize = spirv.size() * sizeof(uint32_t);
|
||||
createInfo.pCode = spirv.data();
|
||||
|
||||
Device* device = ToBackend(GetDevice());
|
||||
|
||||
if (device->fn.CreateShaderModule(device->GetVkDevice(), &createInfo, nullptr, &mHandle) !=
|
||||
VK_SUCCESS) {
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
ShaderModule::~ShaderModule() {
|
||||
Device* device = ToBackend(GetDevice());
|
||||
|
||||
if (mHandle != VK_NULL_HANDLE) {
|
||||
device->GetFencedDeleter()->DeleteWhenUnused(mHandle);
|
||||
mHandle = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
VkShaderModule ShaderModule::GetHandle() const {
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
}} // namespace backend::vulkan
|
|
@ -0,0 +1,37 @@
|
|||
// 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_SHADERMODULEVK_H_
|
||||
#define BACKEND_VULKAN_SHADERMODULEVK_H_
|
||||
|
||||
#include "backend/ShaderModule.h"
|
||||
|
||||
#include "backend/vulkan/vulkan_platform.h"
|
||||
|
||||
namespace backend { namespace vulkan {
|
||||
|
||||
class ShaderModule : public ShaderModuleBase {
|
||||
public:
|
||||
ShaderModule(ShaderModuleBuilder* builder);
|
||||
~ShaderModule();
|
||||
|
||||
VkShaderModule GetHandle() const;
|
||||
|
||||
private:
|
||||
VkShaderModule mHandle = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
}} // namespace backend::vulkan
|
||||
|
||||
#endif // BACKEND_VULKAN_SHADERMODULEVK_H_
|
|
@ -23,6 +23,8 @@
|
|||
#include "backend/vulkan/InputStateVk.h"
|
||||
#include "backend/vulkan/PipelineLayoutVk.h"
|
||||
#include "backend/vulkan/RenderPassVk.h"
|
||||
#include "backend/vulkan/RenderPipelineVk.h"
|
||||
#include "backend/vulkan/ShaderModuleVk.h"
|
||||
#include "backend/vulkan/TextureVk.h"
|
||||
#include "common/Platform.h"
|
||||
|
||||
|
@ -223,12 +225,7 @@ namespace backend { namespace vulkan {
|
|||
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;
|
||||
return new ShaderModule(builder);
|
||||
}
|
||||
SwapChainBase* Device::CreateSwapChain(SwapChainBuilder* builder) {
|
||||
return new SwapChain(builder);
|
||||
|
|
|
@ -24,9 +24,7 @@
|
|||
#include "backend/DepthStencilState.h"
|
||||
#include "backend/Device.h"
|
||||
#include "backend/Queue.h"
|
||||
#include "backend/RenderPipeline.h"
|
||||
#include "backend/Sampler.h"
|
||||
#include "backend/ShaderModule.h"
|
||||
#include "backend/SwapChain.h"
|
||||
#include "backend/ToBackend.h"
|
||||
#include "backend/vulkan/VulkanFunctions.h"
|
||||
|
@ -53,9 +51,9 @@ namespace backend { namespace vulkan {
|
|||
class PipelineLayout;
|
||||
class Queue;
|
||||
class RenderPass;
|
||||
using RenderPipeline = RenderPipelineBase;
|
||||
class RenderPipeline;
|
||||
using Sampler = SamplerBase;
|
||||
using ShaderModule = ShaderModuleBase;
|
||||
class ShaderModule;
|
||||
class SwapChain;
|
||||
class Texture;
|
||||
class TextureView;
|
||||
|
|
Loading…
Reference in New Issue