Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Reflect stage data
  • Loading branch information
bdero committed Dec 11, 2023
commit fea9317407aa2d583a908a12f08fe30e0c87c0be
31 changes: 29 additions & 2 deletions impeller/compiler/reflector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@
#include <set>
#include <sstream>

#include "flutter/fml/closure.h"
#include "flutter/fml/logging.h"
#include "impeller/base/strings.h"
#include "impeller/base/validation.h"
#include "impeller/compiler/code_gen_template.h"
#include "impeller/compiler/types.h"
#include "impeller/compiler/uniform_sorter.h"
#include "impeller/compiler/utilities.h"
#include "impeller/geometry/half.h"
Expand Down Expand Up @@ -353,6 +351,35 @@ std::shared_ptr<RuntimeStageData> Reflector::GenerateRuntimeStageData() const {
uniform_description.array_elements = GetArrayElements(spir_type);
data->AddUniformDescription(std::move(uniform_description));
}

// We only need to worry about reflecting vertex attributes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't we already reflect over the vertex attributes somewhere in compiler.cc?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, for the reflection C header. We pack the same data here.

if (entrypoints.front().execution_model == spv::ExecutionModelVertex) {
const auto inputs = compiler_->get_shader_resources().stage_inputs;
auto input_offsets = ComputeOffsets(inputs);
for (const auto& input : inputs) {
auto location = compiler_->get_decoration(
input.id, spv::Decoration::DecorationLocation);
std::optional<size_t> offset = input_offsets[location];

const auto type = compiler_->get_type(input.type_id);

InputDescription input_description;
input_description.name = input.name;
input_description.location = compiler_->get_decoration(
input.id, spv::Decoration::DecorationLocation);
input_description.set = compiler_->get_decoration(
input.id, spv::Decoration::DecorationDescriptorSet);
Comment on lines +370 to +371
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI the vulkan backend can't support specifying different descriptor sets right now

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know. I just tried to replicate the way we pack the header template for now. My guess is that we can probably get away with removing a couple of these fields everywhere.

input_description.binding = compiler_->get_decoration(
input.id, spv::Decoration::DecorationBinding);
input_description.type = type.basetype;
input_description.bit_width = type.width;
input_description.vec_size = type.vecsize;
input_description.columns = type.columns;
input_description.offset = offset.value_or(0u);
data->AddInputDescription(std::move(input_description));
}
}

return data;
}

Expand Down
77 changes: 75 additions & 2 deletions impeller/compiler/runtime_stage_data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ void RuntimeStageData::AddUniformDescription(UniformDescription uniform) {
uniforms_.emplace_back(std::move(uniform));
}

void RuntimeStageData::AddInputDescription(InputDescription input) {
inputs_.emplace_back(std::move(input));
}

void RuntimeStageData::SetShaderData(std::shared_ptr<fml::Mapping> shader) {
shader_ = std::move(shader);
}
Expand Down Expand Up @@ -108,7 +112,7 @@ static std::optional<uint32_t> ToJsonTargetPlatform(TargetPlatform platform) {
FML_UNREACHABLE();
}

static std::optional<fb::UniformDataType> ToType(
static std::optional<fb::UniformDataType> ToUniformType(
spirv_cross::SPIRType::BaseType type) {
switch (type) {
case spirv_cross::SPIRType::Boolean:
Expand Down Expand Up @@ -152,6 +156,49 @@ static std::optional<fb::UniformDataType> ToType(
}
FML_UNREACHABLE();
}
static std::optional<fb::InputDataType> ToInputType(
spirv_cross::SPIRType::BaseType type) {
switch (type) {
case spirv_cross::SPIRType::Boolean:
return fb::InputDataType::kBoolean;
case spirv_cross::SPIRType::SByte:
return fb::InputDataType::kSignedByte;
case spirv_cross::SPIRType::UByte:
return fb::InputDataType::kUnsignedByte;
case spirv_cross::SPIRType::Short:
return fb::InputDataType::kSignedShort;
case spirv_cross::SPIRType::UShort:
return fb::InputDataType::kUnsignedShort;
case spirv_cross::SPIRType::Int:
return fb::InputDataType::kSignedInt;
case spirv_cross::SPIRType::UInt:
return fb::InputDataType::kUnsignedInt;
case spirv_cross::SPIRType::Int64:
return fb::InputDataType::kSignedInt64;
case spirv_cross::SPIRType::UInt64:
return fb::InputDataType::kUnsignedInt64;
case spirv_cross::SPIRType::Half:
return fb::InputDataType::kHalfFloat;
case spirv_cross::SPIRType::Float:
return fb::InputDataType::kFloat;
case spirv_cross::SPIRType::Double:
return fb::InputDataType::kDouble;
case spirv_cross::SPIRType::Unknown:
case spirv_cross::SPIRType::Void:
case spirv_cross::SPIRType::AtomicCounter:
case spirv_cross::SPIRType::Struct:
case spirv_cross::SPIRType::Image:
case spirv_cross::SPIRType::SampledImage:
case spirv_cross::SPIRType::Sampler:
case spirv_cross::SPIRType::AccelerationStructure:
case spirv_cross::SPIRType::RayQuery:
case spirv_cross::SPIRType::ControlPointArray:
case spirv_cross::SPIRType::Interpolant:
case spirv_cross::SPIRType::Char:
return std::nullopt;
}
FML_UNREACHABLE();
}

static std::optional<uint32_t> ToJsonType(
spirv_cross::SPIRType::BaseType type) {
Expand Down Expand Up @@ -327,7 +374,7 @@ std::unique_ptr<fb::RuntimeStageT> RuntimeStageData::CreateFlatbuffer() const {
desc->location = uniform.location;
desc->rows = uniform.rows;
desc->columns = uniform.columns;
auto uniform_type = ToType(uniform.type);
auto uniform_type = ToUniformType(uniform.type);
if (!uniform_type.has_value()) {
VALIDATION_LOG << "Invalid uniform type for runtime stage.";
return nullptr;
Expand All @@ -341,6 +388,32 @@ std::unique_ptr<fb::RuntimeStageT> RuntimeStageData::CreateFlatbuffer() const {
runtime_stage->uniforms.emplace_back(std::move(desc));
}

for (const auto& input : inputs_) {
auto desc = std::make_unique<fb::StageInputT>();

desc->name = input.name;

if (desc->name.empty()) {
VALIDATION_LOG << "Stage input name cannot be empty.";
return nullptr;
}
desc->location = input.location;
desc->set = input.set;
desc->binding = input.binding;
auto input_type = ToInputType(input.type);
if (!input_type.has_value()) {
VALIDATION_LOG << "Invalid uniform type for runtime stage.";
return nullptr;
}
desc->type = input_type.value();
desc->bit_width = input.bit_width;
desc->vec_size = input.vec_size;
desc->columns = input.columns;
desc->offset = input.offset;

runtime_stage->inputs.emplace_back(std::move(desc));
}

return runtime_stage;
}

Expand Down
16 changes: 16 additions & 0 deletions impeller/compiler/runtime_stage_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@ struct UniformDescription {
std::optional<size_t> array_elements = std::nullopt;
};

struct InputDescription {
std::string name;
size_t location;
size_t set;
size_t binding;
spirv_cross::SPIRType::BaseType type =
spirv_cross::SPIRType::BaseType::Unknown;
size_t bit_width;
size_t vec_size;
size_t columns;
size_t offset;
};

class RuntimeStageData {
public:
RuntimeStageData(std::string entrypoint,
Expand All @@ -36,6 +49,8 @@ class RuntimeStageData {

void AddUniformDescription(UniformDescription uniform);

void AddInputDescription(InputDescription input);

void SetShaderData(std::shared_ptr<fml::Mapping> shader);

void SetSkSLData(std::shared_ptr<fml::Mapping> sksl);
Expand All @@ -51,6 +66,7 @@ class RuntimeStageData {
const spv::ExecutionModel stage_;
const TargetPlatform target_platform_;
std::vector<UniformDescription> uniforms_;
std::vector<InputDescription> inputs_;
std::shared_ptr<fml::Mapping> shader_;
std::shared_ptr<fml::Mapping> sksl_;

Expand Down
32 changes: 32 additions & 0 deletions impeller/runtime_stage/runtime_stage_types.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ enum TargetPlatform:byte {
kVulkan,
}

// The subset of impeller::ShaderType that may be used for uniform bindings.
enum UniformDataType:uint32 {
kBoolean,
kSignedByte,
Expand All @@ -43,10 +44,41 @@ table UniformDescription {
array_elements: uint64;
}

// The subset of impeller::ShaderType that may be used for vertex attributes.
enum InputDataType:uint32 {
kBoolean,
kSignedByte,
kUnsignedByte,
kSignedShort,
kUnsignedShort,
kSignedInt,
kUnsignedInt,
kSignedInt64,
kUnsignedInt64,
kHalfFloat,
kFloat,
kDouble,
}

// This contains the same attribute reflection data as
// impeller::ShaderStageIOSlot.
table StageInput {
name: string;
location: uint64;
set: uint64;
binding: uint64;
type: InputDataType;
bit_width: uint64;
vec_size: uint64;
columns: uint64;
offset: uint64;
}

table RuntimeStage {
stage: Stage;
target_platform: TargetPlatform;
entrypoint: string;
inputs: [StageInput];
uniforms: [UniformDescription];
shader: [ubyte];
sksl: [ubyte];
Expand Down