Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a way to specify an additional uniform name along with a sampler param for the associated transform matrix #8490

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
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
1 change: 1 addition & 0 deletions NEW_RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
## Release notes for next branch cut

- android: breaking changes to API KTX1Loader::createIndirectLight and KTX1Loader::createSkybox
- materials: add an optional `transformName` field to sampler material parameters. [⚠️ **New Material Version**]
6 changes: 6 additions & 0 deletions filament/src/MaterialParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ bool ChunkUniformInterfaceBlock::unflatten(Unflattener& unflattener,
uint64_t fieldSize = 0;
uint8_t fieldType = 0;
uint8_t fieldPrecision = 0;
uint8_t fieldAssociatedSampler = 0;

if (!unflattener.read(&fieldName)) {
return false;
Expand All @@ -438,8 +439,13 @@ bool ChunkUniformInterfaceBlock::unflatten(Unflattener& unflattener,
return false;
}

if (!unflattener.read(&fieldAssociatedSampler)) {
return false;
}

// a size of 1 means not an array
builder.add({{{ fieldName.data(), fieldName.size() },
fieldAssociatedSampler,
uint32_t(fieldSize == 1 ? 0 : fieldSize),
BufferInterfaceBlock::Type(fieldType),
BufferInterfaceBlock::Precision(fieldPrecision) }});
Expand Down
33 changes: 28 additions & 5 deletions libs/filabridge/include/private/filament/BufferInterfaceBlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,28 @@ class BufferInterfaceBlock {
std::string_view name;
uint32_t size;
backend::UniformType type;
backend::Precision precision{};
backend::FeatureLevel minFeatureLevel = backend::FeatureLevel::FEATURE_LEVEL_1;
std::string_view structName{};
uint32_t stride{};
std::string_view sizeName{};
backend::Precision precision;
uint8_t associatedSampler = 0;
backend::FeatureLevel minFeatureLevel;
std::string_view structName;
uint32_t stride;
std::string_view sizeName;

InterfaceBlockEntry() = default;
InterfaceBlockEntry(std::string_view name, uint32_t size, backend::UniformType type,
backend::Precision precision = {},
backend::FeatureLevel minFeatureLevel = backend::FeatureLevel::FEATURE_LEVEL_1, std::string_view structName = {},
uint32_t stride = {}, std::string_view sizeName = {}) noexcept
: name(name), size(size), type(type), precision(precision),
associatedSampler(0), minFeatureLevel(minFeatureLevel),
structName(structName), stride(stride), sizeName(sizeName) {}
InterfaceBlockEntry(std::string_view name, uint8_t associatedSampler, uint32_t size, backend::UniformType type,
backend::Precision precision = {},
backend::FeatureLevel minFeatureLevel = backend::FeatureLevel::FEATURE_LEVEL_1, std::string_view structName = {},
uint32_t stride = {}, std::string_view sizeName = {}) noexcept
: name(name), size(size), type(type), precision(precision),
associatedSampler(associatedSampler), minFeatureLevel(minFeatureLevel),
structName(structName), stride(stride), sizeName(sizeName) {}
};

BufferInterfaceBlock();
Expand All @@ -68,6 +85,7 @@ class BufferInterfaceBlock {
bool isArray; // true if the field is an array
uint32_t size; // size of the array in elements, or 0 if not an array
Precision precision; // precision of this field
uint8_t associatedSampler; // sampler associated with this field
backend::FeatureLevel minFeatureLevel; // below this feature level, this field is not needed
utils::CString structName; // name of this field structure if type is STRUCT
utils::CString sizeName; // name of the size parameter in the shader
Expand Down Expand Up @@ -152,6 +170,10 @@ class BufferInterfaceBlock {
// negative value if name doesn't exist or Panic if exceptions are enabled
ssize_t getFieldOffset(std::string_view name, size_t index) const;

// returns offset in bytes of the transform matrix for the given external texture binding
// returns -1 if the field doesn't exist
ssize_t getTransformFieldOffset(uint8_t binding) const;

FieldInfo const* getFieldInfo(std::string_view name) const;

bool hasField(std::string_view name) const noexcept {
Expand Down Expand Up @@ -179,6 +201,7 @@ class BufferInterfaceBlock {
utils::CString mName;
utils::FixedCapacityVector<FieldInfo> mFieldInfoList;
std::unordered_map<std::string_view , uint32_t> mInfoMap;
std::unordered_map<uint8_t, uint32_t> mTransformOffsetMap;
uint32_t mSize = 0; // size in bytes rounded to multiple of 4
Alignment mAlignment = Alignment::std140;
Target mTarget = Target::UNIFORM;
Expand Down
21 changes: 18 additions & 3 deletions libs/filabridge/src/BufferInterfaceBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ BufferInterfaceBlock::Builder& BufferInterfaceBlock::Builder::add(
for (auto const& item : list) {
mEntries.push_back({
{ item.name.data(), item.name.size() },
0, uint8_t(item.stride), item.type, item.size > 0, item.size, item.precision, item.minFeatureLevel,
0, uint8_t(item.stride), item.type, item.size > 0, item.size, item.precision, item.associatedSampler, item.minFeatureLevel,
{ item.structName.data(), item.structName.size() },
{ item.sizeName.data(), item.sizeName.size() }
});
Expand All @@ -71,7 +71,7 @@ BufferInterfaceBlock::Builder& BufferInterfaceBlock::Builder::addVariableSizedAr
mHasVariableSizeArray = true;
mEntries.push_back({
{ item.name.data(), item.name.size() },
0, uint8_t(item.stride), item.type, true, 0, item.precision, item.minFeatureLevel,
0, uint8_t(item.stride), item.type, true, 0, item.precision, item.associatedSampler, item.minFeatureLevel,
{ item.structName.data(), item.structName.size() },
{ item.sizeName.data(), item.sizeName.size() }
});
Expand Down Expand Up @@ -122,6 +122,8 @@ BufferInterfaceBlock::BufferInterfaceBlock(Builder const& builder) noexcept

auto& uniformsInfoList = mFieldInfoList;

auto& transformOffsetMap = mTransformOffsetMap;

uint32_t i = 0;
uint16_t offset = 0;
for (auto const& e : builder.mEntries) {
Expand All @@ -143,11 +145,16 @@ BufferInterfaceBlock::BufferInterfaceBlock(Builder const& builder) noexcept

FieldInfo& info = uniformsInfoList[i];
info = { e.name, offset, uint8_t(stride), e.type, e.isArray, e.size,
e.precision, e.minFeatureLevel, e.structName, e.sizeName };
e.precision, e.associatedSampler, e.minFeatureLevel, e.structName, e.sizeName };

// record this uniform info
infoMap[{ info.name.data(), info.name.size() }] = i;

// record the transform offset if this is an external sampler
if (e.associatedSampler != 0) {
transformOffsetMap[e.associatedSampler] = offset;
}

// advance offset to next slot
offset += stride * std::max(1u, e.size);
++i;
Expand All @@ -163,6 +170,14 @@ ssize_t BufferInterfaceBlock::getFieldOffset(std::string_view name, size_t index
return (ssize_t)info->getBufferOffset(index);
}

ssize_t BufferInterfaceBlock::getTransformFieldOffset(uint8_t binding) const {
auto pos = mTransformOffsetMap.find(binding);
if (pos == mTransformOffsetMap.end()) {
return -1;
}
return (ssize_t)pos->second;
}

BufferInterfaceBlock::FieldInfo const* BufferInterfaceBlock::getFieldInfo(
std::string_view name) const {
auto pos = mInfoMap.find(name);
Expand Down
8 changes: 5 additions & 3 deletions libs/filamat/include/filamat/MaterialBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,8 @@ class UTILS_PUBLIC MaterialBuilder : public MaterialBuilderBase {
MaterialBuilder& parameter(const char* name, SamplerType samplerType,
SamplerFormat format = SamplerFormat::FLOAT,
ParameterPrecision precision = ParameterPrecision::DEFAULT,
bool multisample = false) noexcept;
bool multisample = false,
const char* transformName = "") noexcept;

MaterialBuilder& buffer(filament::BufferInterfaceBlock bib) noexcept;

Expand Down Expand Up @@ -648,8 +649,8 @@ class UTILS_PUBLIC MaterialBuilder : public MaterialBuilderBase {
Parameter() noexcept: parameterType(INVALID) {}

// Sampler
Parameter(const char* paramName, SamplerType t, SamplerFormat f, ParameterPrecision p, bool ms)
: name(paramName), size(1), precision(p), samplerType(t), format(f), parameterType(SAMPLER), multisample(ms) { }
Parameter(const char* paramName, SamplerType t, SamplerFormat f, ParameterPrecision p, bool ms, const char* tn)
: name(paramName), size(1), precision(p), samplerType(t), format(f), parameterType(SAMPLER), multisample(ms), transformName(tn) { }

// Uniform
Parameter(const char* paramName, UniformType t, size_t typeSize, ParameterPrecision p)
Expand All @@ -667,6 +668,7 @@ class UTILS_PUBLIC MaterialBuilder : public MaterialBuilderBase {
SubpassType subpassType;
SamplerFormat format;
bool multisample;
utils::CString transformName;
enum {
INVALID,
UNIFORM,
Expand Down
14 changes: 10 additions & 4 deletions libs/filamat/src/MaterialBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ MaterialBuilder& MaterialBuilder::parameter(const char* name, UniformType type,


MaterialBuilder& MaterialBuilder::parameter(const char* name, SamplerType samplerType,
SamplerFormat format, ParameterPrecision precision, bool multisample) noexcept {
SamplerFormat format, ParameterPrecision precision, bool multisample, const char* transformName) noexcept {
FILAMENT_CHECK_PRECONDITION(!multisample ||
(format != SamplerFormat::SHADOW &&
(samplerType == SamplerType::SAMPLER_2D ||
Expand All @@ -288,7 +288,7 @@ MaterialBuilder& MaterialBuilder::parameter(const char* name, SamplerType sample
" as long as type is not SHADOW";

FILAMENT_CHECK_POSTCONDITION(mParameterCount < MAX_PARAMETERS_COUNT) << "Too many parameters";
mParameters[mParameterCount++] = { name, samplerType, format, precision, multisample };
mParameters[mParameterCount++] = { name, samplerType, format, precision, multisample, transformName };
return *this;
}

Expand Down Expand Up @@ -609,12 +609,18 @@ void MaterialBuilder::prepareToBuild(MaterialInfo& info) noexcept {
SamplerInterfaceBlock::Builder sbb;
BufferInterfaceBlock::Builder ibb;
// sampler bindings start at 1, 0 is the ubo
for (size_t i = 0, binding = 1, c = mParameterCount; i < c; i++) {
uint16_t binding = 1;
for (size_t i = 0, c = mParameterCount; i < c; i++) {
auto const& param = mParameters[i];
assert_invariant(!param.isSubpass());
if (param.isSampler()) {
sbb.add({ param.name.data(), param.name.size() },
binding++, param.samplerType, param.format, param.precision, param.multisample);
binding, param.samplerType, param.format, param.precision, param.multisample);
if (!param.transformName.empty()) {
ibb.add({{{ param.transformName.data(), param.transformName.size() }, uint8_t(binding),
0, UniformType::MAT3, Precision::DEFAULT, FeatureLevel::FEATURE_LEVEL_0 }});
}
binding++;
} else if (param.isUniform()) {
ibb.add({{{ param.name.data(), param.name.size() },
uint32_t(param.size == 1u ? 0u : param.size), param.uniformType,
Expand Down
1 change: 1 addition & 0 deletions libs/filamat/src/eiff/MaterialInterfaceBlockChunk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ void MaterialUniformInterfaceBlockChunk::flatten(Flattener& f) {
f.writeUint64(uInfo.size);
f.writeUint8(static_cast<uint8_t>(uInfo.type));
f.writeUint8(static_cast<uint8_t>(uInfo.precision));
f.writeUint8(static_cast<uint8_t>(uInfo.associatedSampler));
}
}

Expand Down
13 changes: 12 additions & 1 deletion tools/matc/src/matc/ParametersProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,12 @@ static bool processParameter(MaterialBuilder& builder, const JsonishObject& json
std::cerr << "parameters: name value must be STRING." << std::endl;
return false;
}

const JsonishValue* transformNameValue = jsonObject.getValue("transformName");
if (transformNameValue && transformNameValue->getType() != JsonishValue::STRING) {
std::cerr << "parameters: transformName value must be STRING." << std::endl;
return false;
}

const JsonishValue* precisionValue = jsonObject.getValue("precision");
if (precisionValue) {
Expand Down Expand Up @@ -221,7 +227,12 @@ static bool processParameter(MaterialBuilder& builder, const JsonishObject& json

auto multisample = multiSampleValue ? multiSampleValue->toJsonBool()->getBool() : false;

builder.parameter(nameString.c_str(), type, format, precision, multisample);
if (transformNameValue) {
auto transformName = transformNameValue->toJsonString()->getString();
builder.parameter(nameString.c_str(), type, format, precision, multisample, transformName.c_str());
} else {
builder.parameter(nameString.c_str(), type, format, precision, multisample);
}

} else {
std::cerr << "parameters: the type '" << typeString
Expand Down