[impeller] Wireup vertex descriptor format for vulkan (flutter/engine#36353)

This commit is contained in:
Kaushik Iska 2022-09-22 15:14:02 -04:00 committed by GitHub
parent 71934b1eb3
commit 7e8494c842
13 changed files with 234 additions and 32 deletions

View File

@ -121,7 +121,10 @@ std::shared_ptr<DeviceBuffer> AllocatorVK::OnCreateBuffer(
// StorageMode.
auto buffer_create_info = static_cast<vk::BufferCreateInfo::NativeType>(
vk::BufferCreateInfo()
.setUsage(vk::BufferUsageFlagBits::eStorageBuffer |
.setUsage(vk::BufferUsageFlagBits::eVertexBuffer |
vk::BufferUsageFlagBits::eIndexBuffer |
vk::BufferUsageFlagBits::eUniformBuffer |
vk::BufferUsageFlagBits::eStorageBuffer |
vk::BufferUsageFlagBits::eTransferSrc |
vk::BufferUsageFlagBits::eTransferDst)
.setSize(desc.size)

View File

@ -67,4 +67,8 @@ bool DeviceBufferVK::SetLabel(const std::string& label, Range range) {
return SetLabel(label);
}
DeviceBufferAllocationVK* DeviceBufferVK::GetAllocation() const {
return device_allocation_.get();
}
} // namespace impeller

View File

@ -45,6 +45,8 @@ class DeviceBufferVK final : public DeviceBuffer,
// |DeviceBuffer|
~DeviceBufferVK() override;
DeviceBufferAllocationVK* GetAllocation() const;
private:
friend class AllocatorVK;

View File

@ -12,6 +12,7 @@
#include "impeller/renderer/backend/vulkan/formats_vk.h"
#include "impeller/renderer/backend/vulkan/pipeline_vk.h"
#include "impeller/renderer/backend/vulkan/shader_function_vk.h"
#include "impeller/renderer/backend/vulkan/vertex_descriptor_vk.h"
namespace impeller {
@ -302,19 +303,20 @@ std::unique_ptr<PipelineCreateInfoVK> PipelineLibraryVK::CreatePipeline(
binding_description.setInputRate(vk::VertexInputRate::eVertex);
std::vector<vk::VertexInputAttributeDescription> attr_descs;
uint32_t stride = 0;
uint32_t offset = 0;
const auto& stage_inputs = desc.GetVertexDescriptor()->GetStageInputs();
for (const ShaderStageIOSlot& stage_in : stage_inputs) {
vk::VertexInputAttributeDescription attr_desc;
attr_desc.setBinding(stage_in.binding);
attr_desc.setLocation(stage_in.location);
attr_desc.setFormat(vk::Format::eR8G8B8A8Unorm);
attr_desc.setOffset(stride);
attr_desc.setFormat(ToVertexDescriptorFormat(stage_in));
attr_desc.setOffset(offset);
attr_descs.push_back(attr_desc);
stride += stage_in.bit_width * stage_in.vec_size;
uint32_t len = (stage_in.bit_width * stage_in.vec_size) / 8;
offset += len;
}
binding_description.setStride(stride);
binding_description.setStride(offset);
vk::PipelineVertexInputStateCreateInfo vertex_input_state;
vertex_input_state.setVertexAttributeDescriptions(attr_descs);
@ -375,8 +377,9 @@ std::unique_ptr<PipelineCreateInfoVK> PipelineLibraryVK::CreatePipeline(
return nullptr;
}
return std::make_unique<PipelineCreateInfoVK>(std::move(pipeline.value),
std::move(render_pass.value()));
return std::make_unique<PipelineCreateInfoVK>(
std::move(pipeline.value), std::move(render_pass.value()),
std::move(pipeline_layout.value), std::move(descriptor_set_layout));
}
} // namespace impeller

View File

@ -6,22 +6,37 @@
namespace impeller {
PipelineCreateInfoVK::PipelineCreateInfoVK(vk::UniquePipeline pipeline,
vk::UniqueRenderPass render_pass)
: pipeline_(std::move(pipeline)), render_pass_(std::move(render_pass)) {
is_valid_ = pipeline_ && render_pass_;
PipelineCreateInfoVK::PipelineCreateInfoVK(
vk::UniquePipeline pipeline,
vk::UniqueRenderPass render_pass,
vk::UniquePipelineLayout layout,
vk::UniqueDescriptorSetLayout descriptor_set_layout)
: pipeline_(std::move(pipeline)),
render_pass_(std::move(render_pass)),
pipeline_layout_(std::move(layout)),
descriptor_set_layout_(std::move(descriptor_set_layout)) {
is_valid_ =
pipeline_ && render_pass_ && pipeline_layout_ && descriptor_set_layout_;
}
bool PipelineCreateInfoVK::IsValid() const {
return is_valid_;
}
vk::UniquePipeline PipelineCreateInfoVK::GetPipeline() {
return std::move(pipeline_);
vk::Pipeline PipelineCreateInfoVK::GetPipeline() const {
return *pipeline_;
}
vk::UniqueRenderPass PipelineCreateInfoVK::GetRenderPass() {
return std::move(render_pass_);
vk::RenderPass PipelineCreateInfoVK::GetRenderPass() const {
return *render_pass_;
}
vk::PipelineLayout PipelineCreateInfoVK::GetPipelineLayout() const {
return *pipeline_layout_;
}
vk::DescriptorSetLayout PipelineCreateInfoVK::GetDescriptorSetLayout() const {
return *descriptor_set_layout_;
}
PipelineVK::PipelineVK(std::weak_ptr<PipelineLibrary> library,
@ -36,4 +51,8 @@ bool PipelineVK::IsValid() const {
return pipeline_info_->IsValid();
}
PipelineCreateInfoVK* PipelineVK::GetCreateInfo() const {
return pipeline_info_.get();
}
} // namespace impeller

View File

@ -16,18 +16,26 @@ namespace impeller {
class PipelineCreateInfoVK {
public:
PipelineCreateInfoVK(vk::UniquePipeline pipeline,
vk::UniqueRenderPass render_pass);
vk::UniqueRenderPass render_pass,
vk::UniquePipelineLayout pipeline_layout,
vk::UniqueDescriptorSetLayout descriptor_set_layout);
bool IsValid() const;
vk::UniquePipeline GetPipeline();
vk::Pipeline GetPipeline() const;
vk::UniqueRenderPass GetRenderPass();
vk::RenderPass GetRenderPass() const;
vk::PipelineLayout GetPipelineLayout() const;
vk::DescriptorSetLayout GetDescriptorSetLayout() const;
private:
bool is_valid_ = false;
vk::UniquePipeline pipeline_;
vk::UniqueRenderPass render_pass_;
vk::UniquePipelineLayout pipeline_layout_;
vk::UniqueDescriptorSetLayout descriptor_set_layout_;
};
class PipelineVK final
@ -41,6 +49,8 @@ class PipelineVK final
// |Pipeline|
~PipelineVK() override;
PipelineCreateInfoVK* GetCreateInfo() const;
private:
friend class PipelineLibraryVK;

View File

@ -22,6 +22,7 @@ std::unique_ptr<SurfaceVK> SurfaceVK::WrapSwapchainImage(
color0_tex.size = swapchain_image->GetSize();
color0_tex.usage = static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
color0_tex.sample_count = SampleCount::kCount1;
color0_tex.storage_mode = StorageMode::kDevicePrivate;
ColorAttachment color0;
auto color_texture_info = std::make_unique<TextureInfoVK>(TextureInfoVK{
@ -35,7 +36,7 @@ std::unique_ptr<SurfaceVK> SurfaceVK::WrapSwapchainImage(
std::move(color_texture_info));
color0.clear_color = Color::DarkSlateGray();
color0.load_action = LoadAction::kClear;
color0.store_action = StoreAction::kStore;
color0.store_action = StoreAction::kDontCare;
TextureDescriptor stencil0_tex;
stencil0_tex.type = TextureType::kTexture2D;
@ -70,7 +71,9 @@ std::unique_ptr<SurfaceVK> SurfaceVK::WrapSwapchainImage(
SurfaceVK::SurfaceVK(RenderTarget target,
SwapchainImageVK* swapchain_image,
SwapCallback swap_callback)
: Surface(target) {}
: Surface(target) {
swap_callback_ = std::move(swap_callback);
}
SurfaceVK::~SurfaceVK() = default;

View File

@ -142,6 +142,10 @@ vk::Image SwapchainImageVK::GetImage() const {
return image_;
}
vk::ImageView SwapchainImageVK::GetImageView() const {
return image_view_.get();
}
SwapchainImageVK::~SwapchainImageVK() = default;
} // namespace impeller

View File

@ -28,6 +28,8 @@ class SwapchainImageVK {
vk::Image GetImage() const;
vk::ImageView GetImageView() const;
private:
vk::Image image_;
vk::UniqueImageView image_view_;

View File

@ -71,6 +71,10 @@ ISize TextureVK::GetSize() const {
return GetTextureDescriptor().size;
}
TextureInfoVK* TextureVK::GetTextureInfo() const {
return texture_info_.get();
}
bool TextureVK::IsWrapped() const {
return texture_info_->backing_type == TextureBackingTypeVK::kWrappedTexture;
}

View File

@ -50,6 +50,8 @@ class TextureVK final : public Texture, public BackendCast<TextureVK, Texture> {
vk::Image GetImage() const;
TextureInfoVK* GetTextureInfo() const;
private:
ContextVK* context_;
std::unique_ptr<TextureInfoVK> texture_info_;

View File

@ -6,8 +6,160 @@
namespace impeller {
VertexDescriptorVK::VertexDescriptorVK() = default;
vk::Format ToVertexDescriptorFormat(const ShaderStageIOSlot& input) {
if (input.columns != 1) {
// All matrix types are unsupported as vertex inputs.
return vk::Format::eUndefined;
}
VertexDescriptorVK::~VertexDescriptorVK() = default;
switch (input.type) {
case ShaderType::kFloat: {
if (input.bit_width == 8 * sizeof(float)) {
switch (input.vec_size) {
case 1:
return vk::Format::eR32Sfloat;
case 2:
return vk::Format::eR32G32Sfloat;
case 3:
return vk::Format::eR32G32B32Sfloat;
case 4:
return vk::Format::eR32G32B32A32Sfloat;
}
}
return vk::Format::eUndefined;
}
case ShaderType::kHalfFloat: {
if (input.bit_width == 8 * sizeof(float) / 2) {
switch (input.vec_size) {
case 1:
return vk::Format::eR16Sfloat;
case 2:
return vk::Format::eR16G16Sfloat;
case 3:
return vk::Format::eR16G16B16Sfloat;
case 4:
return vk::Format::eR16G16B16A16Sfloat;
}
}
return vk::Format::eUndefined;
}
case ShaderType::kDouble: {
// Unsupported.
return vk::Format::eUndefined;
}
case ShaderType::kBoolean: {
if (input.bit_width == 8 * sizeof(bool) && input.vec_size == 1) {
return vk::Format::eR8Uint;
}
return vk::Format::eUndefined;
}
case ShaderType::kSignedByte: {
if (input.bit_width == 8 * sizeof(char)) {
switch (input.vec_size) {
case 1:
return vk::Format::eR8Sint;
case 2:
return vk::Format::eR8G8Sint;
case 3:
return vk::Format::eR8G8B8Sint;
case 4:
return vk::Format::eR8G8B8A8Sint;
}
}
return vk::Format::eUndefined;
}
case ShaderType::kUnsignedByte: {
if (input.bit_width == 8 * sizeof(char)) {
switch (input.vec_size) {
case 1:
return vk::Format::eR8Uint;
case 2:
return vk::Format::eR8G8Uint;
case 3:
return vk::Format::eR8G8B8Uint;
case 4:
return vk::Format::eR8G8B8A8Uint;
}
}
return vk::Format::eUndefined;
}
case ShaderType::kSignedShort: {
if (input.bit_width == 8 * sizeof(short)) {
switch (input.vec_size) {
case 1:
return vk::Format::eR16Sint;
case 2:
return vk::Format::eR16G16Sint;
case 3:
return vk::Format::eR16G16B16Sint;
case 4:
return vk::Format::eR16G16B16A16Sint;
}
}
return vk::Format::eUndefined;
}
case ShaderType::kUnsignedShort: {
if (input.bit_width == 8 * sizeof(ushort)) {
switch (input.vec_size) {
case 1:
return vk::Format::eR16Uint;
case 2:
return vk::Format::eR16G16Uint;
case 3:
return vk::Format::eR16G16B16Uint;
case 4:
return vk::Format::eR16G16B16A16Uint;
}
}
return vk::Format::eUndefined;
}
case ShaderType::kSignedInt: {
if (input.bit_width == 8 * sizeof(int32_t)) {
switch (input.vec_size) {
case 1:
return vk::Format::eR32Sint;
case 2:
return vk::Format::eR32G32Sint;
case 3:
return vk::Format::eR32G32B32Sint;
case 4:
return vk::Format::eR32G32B32A32Sint;
}
}
return vk::Format::eUndefined;
}
case ShaderType::kUnsignedInt: {
if (input.bit_width == 8 * sizeof(uint32_t)) {
switch (input.vec_size) {
case 1:
return vk::Format::eR32Uint;
case 2:
return vk::Format::eR32G32Uint;
case 3:
return vk::Format::eR32G32B32Uint;
case 4:
return vk::Format::eR32G32B32A32Uint;
}
}
return vk::Format::eUndefined;
}
case ShaderType::kSignedInt64: {
// Unsupported.
return vk::Format::eUndefined;
}
case ShaderType::kUnsignedInt64: {
// Unsupported.
return vk::Format::eUndefined;
}
case ShaderType::kAtomicCounter:
case ShaderType::kStruct:
case ShaderType::kImage:
case ShaderType::kSampledImage:
case ShaderType::kUnknown:
case ShaderType::kVoid:
case ShaderType::kSampler:
return vk::Format::eUndefined;
}
}
} // namespace impeller

View File

@ -5,17 +5,11 @@
#pragma once
#include "flutter/fml/macros.h"
#include "impeller/renderer/backend/vulkan/vk.h"
#include "impeller/renderer/shader_types.h"
namespace impeller {
class VertexDescriptorVK {
public:
VertexDescriptorVK();
~VertexDescriptorVK();
private:
FML_DISALLOW_COPY_AND_ASSIGN(VertexDescriptorVK);
};
vk::Format ToVertexDescriptorFormat(const ShaderStageIOSlot& input);
} // namespace impeller