2018-07-18 09:40:26 +00:00
|
|
|
// Copyright 2018 The Dawn Authors
|
2018-01-09 18:50:07 +00:00
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
|
2018-07-24 11:53:51 +00:00
|
|
|
#include "dawn_native/vulkan/RenderPipelineVk.h"
|
|
|
|
|
|
|
|
#include "dawn_native/vulkan/DeviceVk.h"
|
|
|
|
#include "dawn_native/vulkan/FencedDeleter.h"
|
|
|
|
#include "dawn_native/vulkan/PipelineLayoutVk.h"
|
|
|
|
#include "dawn_native/vulkan/RenderPassCache.h"
|
|
|
|
#include "dawn_native/vulkan/ShaderModuleVk.h"
|
2019-04-05 03:06:38 +00:00
|
|
|
#include "dawn_native/vulkan/TextureVk.h"
|
2019-01-04 09:53:50 +00:00
|
|
|
#include "dawn_native/vulkan/UtilsVulkan.h"
|
2019-10-08 08:16:11 +00:00
|
|
|
#include "dawn_native/vulkan/VulkanError.h"
|
2018-01-09 18:50:07 +00:00
|
|
|
|
2018-07-24 14:45:45 +00:00
|
|
|
namespace dawn_native { namespace vulkan {
|
2018-01-09 18:50:07 +00:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2021-07-25 18:40:19 +00:00
|
|
|
VkVertexInputRate VulkanInputRate(wgpu::VertexStepMode stepMode) {
|
2019-03-27 18:08:50 +00:00
|
|
|
switch (stepMode) {
|
2021-07-25 18:40:19 +00:00
|
|
|
case wgpu::VertexStepMode::Vertex:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_VERTEX_INPUT_RATE_VERTEX;
|
2021-07-25 18:40:19 +00:00
|
|
|
case wgpu::VertexStepMode::Instance:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_VERTEX_INPUT_RATE_INSTANCE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-23 11:57:41 +00:00
|
|
|
VkFormat VulkanVertexFormat(wgpu::VertexFormat format) {
|
2019-03-27 18:08:50 +00:00
|
|
|
switch (format) {
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Uint8x2:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R8G8_UINT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Uint8x4:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R8G8B8A8_UINT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Sint8x2:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R8G8_SINT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Sint8x4:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R8G8B8A8_SINT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Unorm8x2:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R8G8_UNORM;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Unorm8x4:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R8G8B8A8_UNORM;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Snorm8x2:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R8G8_SNORM;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Snorm8x4:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R8G8B8A8_SNORM;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Uint16x2:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R16G16_UINT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Uint16x4:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R16G16B16A16_UINT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Sint16x2:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R16G16_SINT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Sint16x4:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R16G16B16A16_SINT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Unorm16x2:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R16G16_UNORM;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Unorm16x4:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R16G16B16A16_UNORM;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Snorm16x2:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R16G16_SNORM;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Snorm16x4:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R16G16B16A16_SNORM;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Float16x2:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R16G16_SFLOAT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Float16x4:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R16G16B16A16_SFLOAT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Float32:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R32_SFLOAT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Float32x2:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R32G32_SFLOAT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Float32x3:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R32G32B32_SFLOAT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Float32x4:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R32G32B32A32_SFLOAT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Uint32:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R32_UINT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Uint32x2:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R32G32_UINT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Uint32x3:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R32G32B32_UINT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Uint32x4:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R32G32B32A32_UINT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Sint32:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R32_SINT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Sint32x2:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R32G32_SINT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Sint32x3:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R32G32B32_SINT;
|
2021-02-26 02:20:25 +00:00
|
|
|
case wgpu::VertexFormat::Sint32x4:
|
2019-03-27 18:08:50 +00:00
|
|
|
return VK_FORMAT_R32G32B32A32_SINT;
|
2021-02-26 02:20:25 +00:00
|
|
|
default:
|
|
|
|
UNREACHABLE();
|
2019-03-27 18:08:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-23 11:57:41 +00:00
|
|
|
VkPrimitiveTopology VulkanPrimitiveTopology(wgpu::PrimitiveTopology topology) {
|
2018-01-09 18:50:07 +00:00
|
|
|
switch (topology) {
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::PrimitiveTopology::PointList:
|
2018-01-09 18:50:07 +00:00
|
|
|
return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::PrimitiveTopology::LineList:
|
2018-01-09 18:50:07 +00:00
|
|
|
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::PrimitiveTopology::LineStrip:
|
2018-01-09 18:50:07 +00:00
|
|
|
return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::PrimitiveTopology::TriangleList:
|
2018-01-09 18:50:07 +00:00
|
|
|
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::PrimitiveTopology::TriangleStrip:
|
2018-01-09 18:50:07 +00:00
|
|
|
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-23 11:57:41 +00:00
|
|
|
bool ShouldEnablePrimitiveRestart(wgpu::PrimitiveTopology topology) {
|
2019-06-03 22:53:29 +00:00
|
|
|
// Primitive restart is always enabled in WebGPU but Vulkan validation rules ask that
|
|
|
|
// primitive restart be only enabled on primitive topologies that support restarting.
|
|
|
|
switch (topology) {
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::PrimitiveTopology::PointList:
|
|
|
|
case wgpu::PrimitiveTopology::LineList:
|
|
|
|
case wgpu::PrimitiveTopology::TriangleList:
|
2019-06-03 22:53:29 +00:00
|
|
|
return false;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::PrimitiveTopology::LineStrip:
|
|
|
|
case wgpu::PrimitiveTopology::TriangleStrip:
|
2019-06-03 22:53:29 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-23 11:57:41 +00:00
|
|
|
VkFrontFace VulkanFrontFace(wgpu::FrontFace face) {
|
2019-07-06 00:11:10 +00:00
|
|
|
switch (face) {
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::FrontFace::CCW:
|
2019-07-06 00:11:10 +00:00
|
|
|
return VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::FrontFace::CW:
|
2019-07-06 00:11:10 +00:00
|
|
|
return VK_FRONT_FACE_CLOCKWISE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-23 11:57:41 +00:00
|
|
|
VkCullModeFlagBits VulkanCullMode(wgpu::CullMode mode) {
|
2019-07-06 00:11:10 +00:00
|
|
|
switch (mode) {
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::CullMode::None:
|
2019-07-06 00:11:10 +00:00
|
|
|
return VK_CULL_MODE_NONE;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::CullMode::Front:
|
2019-07-06 00:11:10 +00:00
|
|
|
return VK_CULL_MODE_FRONT_BIT;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::CullMode::Back:
|
2019-07-06 00:11:10 +00:00
|
|
|
return VK_CULL_MODE_BACK_BIT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-23 11:57:41 +00:00
|
|
|
VkBlendFactor VulkanBlendFactor(wgpu::BlendFactor factor) {
|
2018-12-27 06:32:31 +00:00
|
|
|
switch (factor) {
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::BlendFactor::Zero:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_FACTOR_ZERO;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::BlendFactor::One:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_FACTOR_ONE;
|
2021-04-15 18:34:29 +00:00
|
|
|
case wgpu::BlendFactor::Src:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_FACTOR_SRC_COLOR;
|
2021-04-15 18:34:29 +00:00
|
|
|
case wgpu::BlendFactor::OneMinusSrc:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::BlendFactor::SrcAlpha:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_FACTOR_SRC_ALPHA;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::BlendFactor::OneMinusSrcAlpha:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
2021-04-15 18:34:29 +00:00
|
|
|
case wgpu::BlendFactor::Dst:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_FACTOR_DST_COLOR;
|
2021-04-15 18:34:29 +00:00
|
|
|
case wgpu::BlendFactor::OneMinusDst:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::BlendFactor::DstAlpha:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_FACTOR_DST_ALPHA;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::BlendFactor::OneMinusDstAlpha:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::BlendFactor::SrcAlphaSaturated:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
|
2021-04-15 18:34:29 +00:00
|
|
|
case wgpu::BlendFactor::Constant:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_FACTOR_CONSTANT_COLOR;
|
2021-04-15 18:34:29 +00:00
|
|
|
case wgpu::BlendFactor::OneMinusConstant:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-23 11:57:41 +00:00
|
|
|
VkBlendOp VulkanBlendOperation(wgpu::BlendOperation operation) {
|
2018-12-27 06:32:31 +00:00
|
|
|
switch (operation) {
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::BlendOperation::Add:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_OP_ADD;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::BlendOperation::Subtract:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_OP_SUBTRACT;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::BlendOperation::ReverseSubtract:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_OP_REVERSE_SUBTRACT;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::BlendOperation::Min:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_OP_MIN;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::BlendOperation::Max:
|
2018-12-27 06:32:31 +00:00
|
|
|
return VK_BLEND_OP_MAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-23 11:57:41 +00:00
|
|
|
VkColorComponentFlags VulkanColorWriteMask(wgpu::ColorWriteMask mask,
|
2019-09-30 07:27:57 +00:00
|
|
|
bool isDeclaredInFragmentShader) {
|
2018-12-27 06:32:31 +00:00
|
|
|
// Vulkan and Dawn color write masks match, static assert it and return the mask
|
2019-10-23 11:57:41 +00:00
|
|
|
static_assert(static_cast<VkColorComponentFlagBits>(wgpu::ColorWriteMask::Red) ==
|
2018-12-27 06:32:31 +00:00
|
|
|
VK_COLOR_COMPONENT_R_BIT,
|
|
|
|
"");
|
2019-10-23 11:57:41 +00:00
|
|
|
static_assert(static_cast<VkColorComponentFlagBits>(wgpu::ColorWriteMask::Green) ==
|
2018-12-27 06:32:31 +00:00
|
|
|
VK_COLOR_COMPONENT_G_BIT,
|
|
|
|
"");
|
2019-10-23 11:57:41 +00:00
|
|
|
static_assert(static_cast<VkColorComponentFlagBits>(wgpu::ColorWriteMask::Blue) ==
|
2018-12-27 06:32:31 +00:00
|
|
|
VK_COLOR_COMPONENT_B_BIT,
|
|
|
|
"");
|
2019-10-23 11:57:41 +00:00
|
|
|
static_assert(static_cast<VkColorComponentFlagBits>(wgpu::ColorWriteMask::Alpha) ==
|
2018-12-27 06:32:31 +00:00
|
|
|
VK_COLOR_COMPONENT_A_BIT,
|
|
|
|
"");
|
|
|
|
|
2019-09-30 07:27:57 +00:00
|
|
|
// According to Vulkan SPEC (Chapter 14.3): "The input values to blending or color
|
|
|
|
// attachment writes are undefined for components which do not correspond to a fragment
|
|
|
|
// shader outputs", we set the color write mask to 0 to prevent such undefined values
|
|
|
|
// being written into the color attachments.
|
|
|
|
return isDeclaredInFragmentShader ? static_cast<VkColorComponentFlags>(mask)
|
|
|
|
: static_cast<VkColorComponentFlags>(0);
|
2018-12-27 06:32:31 +00:00
|
|
|
}
|
|
|
|
|
2021-03-22 22:17:26 +00:00
|
|
|
VkPipelineColorBlendAttachmentState ComputeColorDesc(const ColorTargetState* state,
|
2019-09-30 07:27:57 +00:00
|
|
|
bool isDeclaredInFragmentShader) {
|
2018-12-27 06:32:31 +00:00
|
|
|
VkPipelineColorBlendAttachmentState attachment;
|
2021-03-22 22:17:26 +00:00
|
|
|
attachment.blendEnable = state->blend != nullptr ? VK_TRUE : VK_FALSE;
|
|
|
|
if (attachment.blendEnable) {
|
|
|
|
attachment.srcColorBlendFactor = VulkanBlendFactor(state->blend->color.srcFactor);
|
|
|
|
attachment.dstColorBlendFactor = VulkanBlendFactor(state->blend->color.dstFactor);
|
|
|
|
attachment.colorBlendOp = VulkanBlendOperation(state->blend->color.operation);
|
|
|
|
attachment.srcAlphaBlendFactor = VulkanBlendFactor(state->blend->alpha.srcFactor);
|
|
|
|
attachment.dstAlphaBlendFactor = VulkanBlendFactor(state->blend->alpha.dstFactor);
|
|
|
|
attachment.alphaBlendOp = VulkanBlendOperation(state->blend->alpha.operation);
|
|
|
|
} else {
|
|
|
|
// Swiftshader's Vulkan implementation appears to expect these values to be valid
|
|
|
|
// even when blending is not enabled.
|
|
|
|
attachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
|
|
|
|
attachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
|
|
|
|
attachment.colorBlendOp = VK_BLEND_OP_ADD;
|
|
|
|
attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
|
|
|
attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
|
|
|
attachment.alphaBlendOp = VK_BLEND_OP_ADD;
|
|
|
|
}
|
2019-09-30 07:27:57 +00:00
|
|
|
attachment.colorWriteMask =
|
2021-03-22 22:17:26 +00:00
|
|
|
VulkanColorWriteMask(state->writeMask, isDeclaredInFragmentShader);
|
2018-12-27 06:32:31 +00:00
|
|
|
return attachment;
|
|
|
|
}
|
|
|
|
|
2019-10-23 11:57:41 +00:00
|
|
|
VkStencilOp VulkanStencilOp(wgpu::StencilOperation op) {
|
2019-01-04 04:28:37 +00:00
|
|
|
switch (op) {
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::StencilOperation::Keep:
|
2019-01-04 04:28:37 +00:00
|
|
|
return VK_STENCIL_OP_KEEP;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::StencilOperation::Zero:
|
2019-01-04 04:28:37 +00:00
|
|
|
return VK_STENCIL_OP_ZERO;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::StencilOperation::Replace:
|
2019-01-04 04:28:37 +00:00
|
|
|
return VK_STENCIL_OP_REPLACE;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::StencilOperation::IncrementClamp:
|
2019-01-04 04:28:37 +00:00
|
|
|
return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::StencilOperation::DecrementClamp:
|
2019-01-04 04:28:37 +00:00
|
|
|
return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::StencilOperation::Invert:
|
2019-01-04 04:28:37 +00:00
|
|
|
return VK_STENCIL_OP_INVERT;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::StencilOperation::IncrementWrap:
|
2019-01-04 04:28:37 +00:00
|
|
|
return VK_STENCIL_OP_INCREMENT_AND_WRAP;
|
2019-10-23 11:57:41 +00:00
|
|
|
case wgpu::StencilOperation::DecrementWrap:
|
2019-01-04 04:28:37 +00:00
|
|
|
return VK_STENCIL_OP_DECREMENT_AND_WRAP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VkPipelineDepthStencilStateCreateInfo ComputeDepthStencilDesc(
|
2021-03-22 22:17:26 +00:00
|
|
|
const DepthStencilState* descriptor) {
|
2019-01-04 04:28:37 +00:00
|
|
|
VkPipelineDepthStencilStateCreateInfo depthStencilState;
|
|
|
|
depthStencilState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
|
|
|
depthStencilState.pNext = nullptr;
|
|
|
|
depthStencilState.flags = 0;
|
|
|
|
|
|
|
|
// Depth writes only occur if depth is enabled
|
|
|
|
depthStencilState.depthTestEnable =
|
2019-10-23 11:57:41 +00:00
|
|
|
(descriptor->depthCompare == wgpu::CompareFunction::Always &&
|
2019-01-04 04:28:37 +00:00
|
|
|
!descriptor->depthWriteEnabled)
|
|
|
|
? VK_FALSE
|
|
|
|
: VK_TRUE;
|
|
|
|
depthStencilState.depthWriteEnable = descriptor->depthWriteEnabled ? VK_TRUE : VK_FALSE;
|
2019-01-04 09:53:50 +00:00
|
|
|
depthStencilState.depthCompareOp = ToVulkanCompareOp(descriptor->depthCompare);
|
2019-01-04 04:28:37 +00:00
|
|
|
depthStencilState.depthBoundsTestEnable = false;
|
|
|
|
depthStencilState.minDepthBounds = 0.0f;
|
|
|
|
depthStencilState.maxDepthBounds = 1.0f;
|
|
|
|
|
|
|
|
depthStencilState.stencilTestEnable =
|
|
|
|
StencilTestEnabled(descriptor) ? VK_TRUE : VK_FALSE;
|
|
|
|
|
2019-01-30 21:11:43 +00:00
|
|
|
depthStencilState.front.failOp = VulkanStencilOp(descriptor->stencilFront.failOp);
|
|
|
|
depthStencilState.front.passOp = VulkanStencilOp(descriptor->stencilFront.passOp);
|
|
|
|
depthStencilState.front.depthFailOp =
|
|
|
|
VulkanStencilOp(descriptor->stencilFront.depthFailOp);
|
|
|
|
depthStencilState.front.compareOp = ToVulkanCompareOp(descriptor->stencilFront.compare);
|
|
|
|
|
|
|
|
depthStencilState.back.failOp = VulkanStencilOp(descriptor->stencilBack.failOp);
|
|
|
|
depthStencilState.back.passOp = VulkanStencilOp(descriptor->stencilBack.passOp);
|
|
|
|
depthStencilState.back.depthFailOp =
|
|
|
|
VulkanStencilOp(descriptor->stencilBack.depthFailOp);
|
|
|
|
depthStencilState.back.compareOp = ToVulkanCompareOp(descriptor->stencilBack.compare);
|
2019-01-04 04:28:37 +00:00
|
|
|
|
|
|
|
// Dawn doesn't have separate front and back stencil masks.
|
|
|
|
depthStencilState.front.compareMask = descriptor->stencilReadMask;
|
|
|
|
depthStencilState.back.compareMask = descriptor->stencilReadMask;
|
|
|
|
depthStencilState.front.writeMask = descriptor->stencilWriteMask;
|
|
|
|
depthStencilState.back.writeMask = descriptor->stencilWriteMask;
|
|
|
|
|
|
|
|
// The stencil reference is always dynamic
|
|
|
|
depthStencilState.front.reference = 0;
|
|
|
|
depthStencilState.back.reference = 0;
|
|
|
|
|
|
|
|
return depthStencilState;
|
|
|
|
}
|
|
|
|
|
2018-01-09 18:50:07 +00:00
|
|
|
} // anonymous namespace
|
|
|
|
|
2019-10-08 08:16:11 +00:00
|
|
|
// static
|
2021-03-31 18:36:32 +00:00
|
|
|
ResultOrError<Ref<RenderPipeline>> RenderPipeline::Create(
|
2019-10-08 08:16:11 +00:00
|
|
|
Device* device,
|
2021-05-21 05:01:38 +00:00
|
|
|
const RenderPipelineDescriptor* descriptor) {
|
2020-04-06 18:20:02 +00:00
|
|
|
Ref<RenderPipeline> pipeline = AcquireRef(new RenderPipeline(device, descriptor));
|
2021-09-15 01:41:42 +00:00
|
|
|
DAWN_TRY(pipeline->Initialize());
|
2021-03-31 18:36:32 +00:00
|
|
|
return pipeline;
|
2019-10-08 08:16:11 +00:00
|
|
|
}
|
|
|
|
|
2021-09-15 01:41:42 +00:00
|
|
|
MaybeError RenderPipeline::Initialize() {
|
2019-10-08 08:16:11 +00:00
|
|
|
Device* device = ToBackend(GetDevice());
|
|
|
|
|
2021-09-15 03:17:42 +00:00
|
|
|
// There are at most 2 shader stages in render pipeline, i.e. vertex and fragment
|
|
|
|
std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages;
|
|
|
|
uint32_t stageCount = 0;
|
|
|
|
|
|
|
|
for (auto stage : IterateStages(this->GetStageMask())) {
|
|
|
|
VkPipelineShaderStageCreateInfo shaderStage;
|
|
|
|
|
|
|
|
DAWN_TRY_ASSIGN(shaderStage.module,
|
|
|
|
ToBackend(GetStage(stage).module)
|
|
|
|
->GetTransformedModuleHandle(GetStage(stage).entryPoint.c_str(),
|
2021-08-10 02:56:03 +00:00
|
|
|
ToBackend(GetLayout())));
|
2021-09-15 03:17:42 +00:00
|
|
|
|
|
|
|
shaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
|
|
|
shaderStage.pNext = nullptr;
|
|
|
|
shaderStage.flags = 0;
|
|
|
|
shaderStage.pSpecializationInfo = nullptr;
|
|
|
|
shaderStage.pName = GetStage(stage).entryPoint.c_str();
|
|
|
|
|
|
|
|
switch (stage) {
|
|
|
|
case dawn_native::SingleShaderStage::Vertex: {
|
|
|
|
shaderStage.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case dawn_native::SingleShaderStage::Fragment: {
|
|
|
|
shaderStage.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
// For render pipeline only Vertex and Fragment stage is possible
|
|
|
|
DAWN_UNREACHABLE();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DAWN_ASSERT(stageCount < 2);
|
|
|
|
shaderStages[stageCount] = shaderStage;
|
|
|
|
stageCount++;
|
2018-01-09 18:50:07 +00:00
|
|
|
}
|
|
|
|
|
2019-11-07 22:23:29 +00:00
|
|
|
PipelineVertexInputStateCreateInfoTemporaryAllocations tempAllocations;
|
2019-05-22 22:46:32 +00:00
|
|
|
VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo =
|
2019-11-07 22:23:29 +00:00
|
|
|
ComputeVertexInputDesc(&tempAllocations);
|
2019-03-27 18:08:50 +00:00
|
|
|
|
2018-01-09 18:50:07 +00:00
|
|
|
VkPipelineInputAssemblyStateCreateInfo inputAssembly;
|
|
|
|
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
|
|
|
inputAssembly.pNext = nullptr;
|
|
|
|
inputAssembly.flags = 0;
|
|
|
|
inputAssembly.topology = VulkanPrimitiveTopology(GetPrimitiveTopology());
|
2019-06-03 22:53:29 +00:00
|
|
|
inputAssembly.primitiveRestartEnable = ShouldEnablePrimitiveRestart(GetPrimitiveTopology());
|
2018-01-09 18:50:07 +00:00
|
|
|
|
|
|
|
// 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;
|
2021-09-10 01:33:41 +00:00
|
|
|
rasterization.depthClampEnable = ShouldClampDepth() ? VK_TRUE : VK_FALSE;
|
2018-01-09 18:50:07 +00:00
|
|
|
rasterization.rasterizerDiscardEnable = VK_FALSE;
|
|
|
|
rasterization.polygonMode = VK_POLYGON_MODE_FILL;
|
2019-07-06 00:11:10 +00:00
|
|
|
rasterization.cullMode = VulkanCullMode(GetCullMode());
|
|
|
|
rasterization.frontFace = VulkanFrontFace(GetFrontFace());
|
2020-10-06 08:12:29 +00:00
|
|
|
rasterization.depthBiasEnable = IsDepthBiasEnabled();
|
|
|
|
rasterization.depthBiasConstantFactor = GetDepthBias();
|
|
|
|
rasterization.depthBiasClamp = GetDepthBiasClamp();
|
|
|
|
rasterization.depthBiasSlopeFactor = GetDepthBiasSlopeScale();
|
2018-01-09 18:50:07 +00:00
|
|
|
rasterization.lineWidth = 1.0f;
|
|
|
|
|
|
|
|
VkPipelineMultisampleStateCreateInfo multisample;
|
|
|
|
multisample.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
|
|
|
multisample.pNext = nullptr;
|
|
|
|
multisample.flags = 0;
|
2019-04-05 03:06:38 +00:00
|
|
|
multisample.rasterizationSamples = VulkanSampleCount(GetSampleCount());
|
2018-01-09 18:50:07 +00:00
|
|
|
multisample.sampleShadingEnable = VK_FALSE;
|
|
|
|
multisample.minSampleShading = 0.0f;
|
2020-07-23 11:30:56 +00:00
|
|
|
// VkPipelineMultisampleStateCreateInfo.pSampleMask is an array of length
|
|
|
|
// ceil(rasterizationSamples / 32) and since we're passing a single uint32_t
|
|
|
|
// we have to assert that this length is indeed 1.
|
|
|
|
ASSERT(multisample.rasterizationSamples <= 32);
|
|
|
|
VkSampleMask sampleMask = GetSampleMask();
|
|
|
|
multisample.pSampleMask = &sampleMask;
|
2021-04-02 19:42:28 +00:00
|
|
|
multisample.alphaToCoverageEnable = IsAlphaToCoverageEnabled();
|
2018-01-09 18:50:07 +00:00
|
|
|
multisample.alphaToOneEnable = VK_FALSE;
|
|
|
|
|
2019-01-04 04:28:37 +00:00
|
|
|
VkPipelineDepthStencilStateCreateInfo depthStencilState =
|
2021-03-22 22:17:26 +00:00
|
|
|
ComputeDepthStencilDesc(GetDepthStencilState());
|
2019-01-04 04:28:37 +00:00
|
|
|
|
2021-09-15 03:17:42 +00:00
|
|
|
VkPipelineColorBlendStateCreateInfo colorBlend;
|
|
|
|
// colorBlend may hold pointers to elements in colorBlendAttachments, so it must have a
|
|
|
|
// definition scope as same as colorBlend
|
2020-09-09 00:08:38 +00:00
|
|
|
ityp::array<ColorAttachmentIndex, VkPipelineColorBlendAttachmentState, kMaxColorAttachments>
|
|
|
|
colorBlendAttachments;
|
2021-09-15 03:17:42 +00:00
|
|
|
if (GetStageMask() & wgpu::ShaderStage::Fragment) {
|
|
|
|
// Initialize the "blend state info" that will be chained in the "create info" from the
|
|
|
|
// data pre-computed in the ColorState
|
|
|
|
const auto& fragmentOutputsWritten =
|
|
|
|
GetStage(SingleShaderStage::Fragment).metadata->fragmentOutputsWritten;
|
|
|
|
for (ColorAttachmentIndex i : IterateBitSet(GetColorAttachmentsMask())) {
|
|
|
|
const ColorTargetState* target = GetColorTargetState(i);
|
|
|
|
colorBlendAttachments[i] = ComputeColorDesc(target, fragmentOutputsWritten[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
colorBlend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
|
|
|
colorBlend.pNext = nullptr;
|
|
|
|
colorBlend.flags = 0;
|
|
|
|
// LogicOp isn't supported so we disable it.
|
|
|
|
colorBlend.logicOpEnable = VK_FALSE;
|
|
|
|
colorBlend.logicOp = VK_LOGIC_OP_CLEAR;
|
|
|
|
colorBlend.attachmentCount = static_cast<uint32_t>(GetColorAttachmentsMask().count());
|
|
|
|
colorBlend.pAttachments = colorBlendAttachments.data();
|
|
|
|
// The blend constant is always dynamic so we fill in a dummy value
|
|
|
|
colorBlend.blendConstants[0] = 0.0f;
|
|
|
|
colorBlend.blendConstants[1] = 0.0f;
|
|
|
|
colorBlend.blendConstants[2] = 0.0f;
|
|
|
|
colorBlend.blendConstants[3] = 0.0f;
|
2018-01-09 18:50:07 +00:00
|
|
|
}
|
|
|
|
|
2020-10-06 08:12:29 +00:00
|
|
|
// Tag all state as dynamic but stencil masks and depth bias.
|
2018-01-09 18:50:07 +00:00
|
|
|
VkDynamicState dynamicStates[] = {
|
2020-10-06 08:12:29 +00:00
|
|
|
VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR,
|
|
|
|
VK_DYNAMIC_STATE_LINE_WIDTH, VK_DYNAMIC_STATE_BLEND_CONSTANTS,
|
|
|
|
VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_REFERENCE,
|
2018-01-09 18:50:07 +00:00
|
|
|
};
|
|
|
|
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;
|
|
|
|
|
2018-05-02 22:10:13 +00:00
|
|
|
// Get a VkRenderPass that matches the attachment formats for this pipeline, load ops don't
|
|
|
|
// matter so set them all to LoadOp::Load
|
|
|
|
VkRenderPass renderPass = VK_NULL_HANDLE;
|
|
|
|
{
|
|
|
|
RenderPassCacheQuery query;
|
|
|
|
|
2020-09-09 00:08:38 +00:00
|
|
|
for (ColorAttachmentIndex i : IterateBitSet(GetColorAttachmentsMask())) {
|
2019-10-23 11:57:41 +00:00
|
|
|
query.SetColor(i, GetColorAttachmentFormat(i), wgpu::LoadOp::Load, false);
|
2018-05-02 22:10:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (HasDepthStencilAttachment()) {
|
2019-10-23 11:57:41 +00:00
|
|
|
query.SetDepthStencil(GetDepthStencilFormat(), wgpu::LoadOp::Load,
|
|
|
|
wgpu::LoadOp::Load);
|
2018-05-02 22:10:13 +00:00
|
|
|
}
|
|
|
|
|
2019-04-05 03:06:38 +00:00
|
|
|
query.SetSampleCount(GetSampleCount());
|
|
|
|
|
2019-10-11 11:17:22 +00:00
|
|
|
DAWN_TRY_ASSIGN(renderPass, device->GetRenderPassCache()->GetRenderPass(query));
|
2018-05-02 22:10:13 +00:00
|
|
|
}
|
|
|
|
|
2018-01-09 18:50:07 +00:00
|
|
|
// 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;
|
2021-09-15 03:17:42 +00:00
|
|
|
createInfo.stageCount = stageCount;
|
|
|
|
createInfo.pStages = shaderStages.data();
|
2019-05-22 22:46:32 +00:00
|
|
|
createInfo.pVertexInputState = &vertexInputCreateInfo;
|
2018-01-09 18:50:07 +00:00
|
|
|
createInfo.pInputAssemblyState = &inputAssembly;
|
|
|
|
createInfo.pTessellationState = nullptr;
|
|
|
|
createInfo.pViewportState = &viewport;
|
|
|
|
createInfo.pRasterizationState = &rasterization;
|
|
|
|
createInfo.pMultisampleState = &multisample;
|
2019-01-04 04:28:37 +00:00
|
|
|
createInfo.pDepthStencilState = &depthStencilState;
|
2021-09-15 03:17:42 +00:00
|
|
|
createInfo.pColorBlendState =
|
|
|
|
(GetStageMask() & wgpu::ShaderStage::Fragment) ? &colorBlend : nullptr;
|
2018-01-09 18:50:07 +00:00
|
|
|
createInfo.pDynamicState = &dynamic;
|
|
|
|
createInfo.layout = ToBackend(GetLayout())->GetHandle();
|
2018-05-02 22:10:13 +00:00
|
|
|
createInfo.renderPass = renderPass;
|
|
|
|
createInfo.subpass = 0;
|
2020-01-31 04:04:16 +00:00
|
|
|
createInfo.basePipelineHandle = VkPipeline{};
|
2018-01-09 18:50:07 +00:00
|
|
|
createInfo.basePipelineIndex = -1;
|
|
|
|
|
2021-09-02 18:39:53 +00:00
|
|
|
DAWN_TRY(CheckVkSuccess(
|
2020-01-31 04:04:16 +00:00
|
|
|
device->fn.CreateGraphicsPipelines(device->GetVkDevice(), VkPipelineCache{}, 1,
|
|
|
|
&createInfo, nullptr, &*mHandle),
|
2021-09-02 18:39:53 +00:00
|
|
|
"CreateGraphicsPipeline"));
|
|
|
|
|
|
|
|
SetLabelImpl();
|
|
|
|
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
void RenderPipeline::SetLabelImpl() {
|
|
|
|
SetDebugName(ToBackend(GetDevice()), VK_OBJECT_TYPE_PIPELINE,
|
|
|
|
reinterpret_cast<uint64_t&>(mHandle), "Dawn_RenderPipeline", GetLabel());
|
2018-01-09 18:50:07 +00:00
|
|
|
}
|
|
|
|
|
2019-05-22 22:46:32 +00:00
|
|
|
VkPipelineVertexInputStateCreateInfo RenderPipeline::ComputeVertexInputDesc(
|
2019-11-07 22:23:29 +00:00
|
|
|
PipelineVertexInputStateCreateInfoTemporaryAllocations* tempAllocations) {
|
2019-03-27 18:08:50 +00:00
|
|
|
// Fill in the "binding info" that will be chained in the create info
|
|
|
|
uint32_t bindingCount = 0;
|
2020-09-17 19:07:00 +00:00
|
|
|
for (VertexBufferSlot slot : IterateBitSet(GetVertexBufferSlotsUsed())) {
|
|
|
|
const VertexBufferInfo& bindingInfo = GetVertexBuffer(slot);
|
2019-03-27 18:08:50 +00:00
|
|
|
|
2019-11-07 22:23:29 +00:00
|
|
|
VkVertexInputBindingDescription* bindingDesc = &tempAllocations->bindings[bindingCount];
|
2020-09-17 19:07:00 +00:00
|
|
|
bindingDesc->binding = static_cast<uint8_t>(slot);
|
2019-11-07 22:23:29 +00:00
|
|
|
bindingDesc->stride = bindingInfo.arrayStride;
|
|
|
|
bindingDesc->inputRate = VulkanInputRate(bindingInfo.stepMode);
|
2019-03-27 18:08:50 +00:00
|
|
|
|
|
|
|
bindingCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fill in the "attribute info" that will be chained in the create info
|
|
|
|
uint32_t attributeCount = 0;
|
2020-09-17 19:07:00 +00:00
|
|
|
for (VertexAttributeLocation loc : IterateBitSet(GetAttributeLocationsUsed())) {
|
|
|
|
const VertexAttributeInfo& attributeInfo = GetAttribute(loc);
|
2019-03-27 18:08:50 +00:00
|
|
|
|
2019-11-07 22:23:29 +00:00
|
|
|
VkVertexInputAttributeDescription* attributeDesc =
|
|
|
|
&tempAllocations->attributes[attributeCount];
|
2020-09-17 19:07:00 +00:00
|
|
|
attributeDesc->location = static_cast<uint8_t>(loc);
|
|
|
|
attributeDesc->binding = static_cast<uint8_t>(attributeInfo.vertexBufferSlot);
|
2019-11-07 22:23:29 +00:00
|
|
|
attributeDesc->format = VulkanVertexFormat(attributeInfo.format);
|
|
|
|
attributeDesc->offset = attributeInfo.offset;
|
2019-03-27 18:08:50 +00:00
|
|
|
|
|
|
|
attributeCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Build the create info
|
2021-09-22 09:25:05 +00:00
|
|
|
VkPipelineVertexInputStateCreateInfo createInfo;
|
|
|
|
createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
|
|
|
createInfo.pNext = nullptr;
|
|
|
|
createInfo.flags = 0;
|
|
|
|
createInfo.vertexBindingDescriptionCount = bindingCount;
|
|
|
|
createInfo.pVertexBindingDescriptions = tempAllocations->bindings.data();
|
|
|
|
createInfo.vertexAttributeDescriptionCount = attributeCount;
|
|
|
|
createInfo.pVertexAttributeDescriptions = tempAllocations->attributes.data();
|
|
|
|
return createInfo;
|
2019-03-27 18:08:50 +00:00
|
|
|
}
|
|
|
|
|
2018-01-09 18:50:07 +00:00
|
|
|
RenderPipeline::~RenderPipeline() {
|
|
|
|
if (mHandle != VK_NULL_HANDLE) {
|
2018-12-10 19:47:22 +00:00
|
|
|
ToBackend(GetDevice())->GetFencedDeleter()->DeleteWhenUnused(mHandle);
|
2018-01-09 18:50:07 +00:00
|
|
|
mHandle = VK_NULL_HANDLE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VkPipeline RenderPipeline::GetHandle() const {
|
|
|
|
return mHandle;
|
|
|
|
}
|
|
|
|
|
2018-07-24 14:45:45 +00:00
|
|
|
}} // namespace dawn_native::vulkan
|